普及组第一题 买铅笔

水题,连循环都不需要。100 分代码如下:

#include"stdio.h"
int main()
{freopen("pencil.in","r",stdin);freopen("pencil.out","w",stdout);int cost,n,number,price;scanf("%d",&n);scanf("%d %d",&number,&price);cost=(n/number+(n%number>0))*price;scanf("%d %d",&number,&price);if(cost>(n/number+(n%number>0))*price)cost=(n/number+(n%number>0))*price;scanf("%d %d",&number,&price);if(cost>(n/number+(n%number>0))*price)cost=(n/number+(n%number>0))*price;printf("%d",cost);return 0;
}

普及组第二题 回文日期

此题只需枚举年份,利用回文串的性质构造出整个日期串,判断是否合法且在区间内即可。100 分代码如下:

#include"stdio.h"
int monthday[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool leapyear(int year)
{return year%400==0||year%100>0&&year%4==0;
}
bool judge(int year)
{bool res=false;int day=year/100%10*10+year/1000,month=year%10*10+year/10%10;if(leapyear(year))monthday[2]++;if(month>0&&month<13&&day>0&&day<=monthday[month])res=true;if(leapyear(year))monthday[2]--;return res;
}
int main()
{freopen("date.in","r",stdin);freopen("date.out","w",stdout);int date1,date2,sum=0,year;scanf("%d\n%d",&date1,&date2);year=date1/10000*10000+date1/10000%10*1000+date1/100000%10*100+date1/1000000%10*10+date1/10000000;if(date1<=year&&judge(date1/10000))sum++;for(year=date1/10000+1;year<date2/10000;year++)if(judge(year))sum++;year=date2/10000*10000+date2/10000%10*1000+date2/100000%10*100+date2/1000000%10*10+date2/10000000;if(date1/10000<date2/10000&&date2>=year&&judge(date2/10000))sum++;printf("%d",sum);return 0;
}

普及组第三题 海港

这道题也不难。设一个状态数组 nation[i] 记下所有国籍为 i 的乘客中最晚到达海港的乘客所乘坐的船的编号,这样的乘客不存在时 nation[i] = 0。对于每只船进港,依次处理该船上每个乘客,判断当前状态是否比状态数组中所记状态更优,是则更新。当出现原海港中没有该国籍的乘客时,计数器增加。随后将当前可以出港的船只依次处理每一个出港乘客,当出现该乘客国籍所对应的状态数组中所记状态恰为当前出港船只编号时,令 nation[i] = 0,计数器减小。具体实现过程详见代码。100 分代码如下:

#include"stdio.h"
#include"string.h"
int k[100005],nation[100005],t[100005],x[300005];
int main()
{freopen("port.in","r",stdin);freopen("port.out","w",stdout);int front=1,n,sum=0;scanf("%d",&n);k[0]=0;memset(nation,0,sizeof(nation));for(int rear=1;rear<=n;rear++){scanf("%d %d",&t[rear],&k[rear]);k[rear]+=k[rear-1];for(int i=k[rear-1];i<k[rear];i++){scanf("%d",&x[i]);if(nation[x[i]]==0)sum++;nation[x[i]]=rear;}for(;t[rear]-t[front]>=86400;front++)for(int i=k[front-1];i<k[front];i++)if(nation[x[i]]==front)nation[x[i]]=0,sum--;printf("%d\n",sum);}return 0;
}

普及组第四题 魔法阵

搜索加剪枝,可以过大半的数据。85 分代码如下:

#include"stdio.h"
#include"string.h"
int num[15005],suma[15005],sumb[15005],sumc[15005],sumd[15005],x[40005];
int main()
{freopen("magic.in","r",stdin);freopen("magic.out","w",stdout);int m,n;scanf("%d %d",&n,&m);memset(num,0,sizeof(num));for(int i=1;i<=m;i++)scanf("%d",&x[i]),num[x[i]]++;memset(suma,0,sizeof(suma));memset(sumb,0,sizeof(sumb));memset(sumc,0,sizeof(sumc));memset(sumd,0,sizeof(sumd));for(int i=1;i+9<n;i++)if(num[i]>0)for(int j=1;i+j*9<n;j++)if(num[i+2*j]>0)for(int k=i+8*j+1;j+k<=n;k++)if(num[k]>0&&num[j+k]>0)suma[i]+=num[i+2*j]*num[k]*num[j+k],sumb[i+2*j]+=num[i]*num[k]*num[j+k],sumc[k]+=num[i]*num[i+2*j]*num[j+k],sumd[j+k]+=num[i]*num[i+2*j]*num[k];for(int i=1;i<=m;i++)printf("%d %d %d %d\n",suma[x[i]],sumb[x[i]],sumc[x[i]],sumd[x[i]]);return 0;
}

提高组第一天第一题 玩具谜题

直接模拟即可。100 分代码如下:

#include"iostream"
#include"stdio.h"
using namespace std;
char name[100005][15];
int dir[100005];
int main()
{freopen("toy.in","r",stdin);freopen("toy.out","w",stdout);int a,ans=1,m,n,s;scanf("%d %d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&dir[i]),cin>>name[i];while(m--){scanf("%d %d",&a,&s);if(a^dir[ans])ans=(ans+s-1)%n+1;elseans=(ans-s+n-1)%n+1;}cout<<name[ans];return 0;
}

提高组第一天第二题 天天爱跑步

对于 s=t,w=0 和 s=1 的点可以搜索过,这样就是 45 分了。剩下的点用树链剖分可以做,具体做法是对树轻重链剖分,在 dfs 序搜索以某一点为根的子树时先搜索该点的轻儿子,暴力添加影响,暴力消除影响,搜索完轻儿子后再搜索重儿子,暴力添加影响,无需消除影响。最后搜索该点时,由于重儿子所在子树影响未消除,故只需暴力加上所有轻儿子所在子树影响。该做法的时间复杂度为 O(nlogn)。

暴力加上影响和暴力消除影响的做法,笔者的思想是在每个节点上增加三个指针,分别指向所有在该点起始的移动单位、在该点终止的移动单位、起始点和终止点的最近公共祖先位于该点的移动单位的链表。暴力添加或消除影响时只需搜索在以该点为根的子树中起始和终止的移动单位,注意判重。对于起始点和终止点都在以当前搜索点为根的子树中,但最近公共祖先的深度大于当前搜索点深度,所以该移动单位不经过当前搜索点的情况的处理,笔者的思想是在搜索过程退出某一点时,此时以该点为根的子树中的所有节点都必然已经搜索完成,则将所有以该点为起始点和终止点的最近公共祖先的移动单位从起始点和终止点的两条指针链中删除。由于朴素的链表删除时间花费较大,所以笔者将起始点链表和终止点链表写成了双向链表的形式,而将无需删除的最近公共祖先链表只写成朴素的链表形式。

关于最后的统计部分,笔者保存以深度为下标的统计数组,对于从起始点链表搜索到的移动单位,即起始点位于以当前搜索点为根的子树中的移动单位,将其起始点的绝对深度对应的统计数值累加。对于从终止点链表搜索到的移动单位,即终止点位于以当前搜索点为根的子树中的移动单位,将其起始点的相对深度对应的统计数值累加,起始点的相对深度为两倍的最近公共祖先的绝对深度减去起始点的绝对深度的值。这个相对深度的值满足当前搜索点与相对深度的深度差等于当前搜索点到起始点的距离。由于相对深度可能为负,所以需要加上一个常数。

关于相对深度的正确性,论证分为以下三种情形:
情形一:起始点位于以当前搜索点为根的子树中,终止点位于以当前搜索点为根的子树外。此时用绝对深度表示,显然成立。
情形二:起始点位于以当前搜索点为根的子树外,终止点位于以当前搜索点为根的子树中。此时当前搜索点和起始点必然是位于最近公共祖先的不同子节点下的,则当前搜索点到起始点的路径必然经过最近公共祖先,而相对深度位于最近公共祖先之上,而相对深度减去最近公共祖先深度等于最近公共祖先深度减去起始点深度,所以相对深度成立。
情形三:起始点和终止点都位于以当前搜索点为根的子树中。此时当且仅当当前搜索点为最近公共祖先(否则在搜索到当前点之前该移动单位已经被删除),而根据相对深度的计算公式,显然成立。

由于卡常数的原因,树链剖分不能满分。95 分代码如下:

#include"stdio.h"
#define MAX_N (400000)
int ans[MAX_N],m,n,opt[MAX_N],skp=0,sum[MAX_N<<1],w[MAX_N];
struct E
{int nxt,toi;
}edge[MAX_N<<1];
struct V
{int dep,fah,fsn,gfa,siz,son,toa,tos,tot;
}vertex[MAX_N];
struct RUNER
{int lca,lsts,lstt,nxtlca,nxts,nxtt,s,t;
}runner[MAX_N];
void dfs0(int now,int fah)
{vertex[now].dep=vertex[fah].dep+1;vertex[now].fah=fah;vertex[now].fsn=0;vertex[now].siz=1;if(edge[vertex[now].son].toi==fah)vertex[now].son=edge[vertex[now].son].nxt;elsefor(int i=vertex[now].son;edge[i].nxt>-1;i=edge[i].nxt)if(edge[edge[i].nxt].toi==fah){edge[i].nxt=edge[edge[i].nxt].nxt;break;}for(int i=vertex[now].son;i>-1;i=edge[i].nxt){dfs0(edge[i].toi,now);if(vertex[vertex[now].fsn].siz<vertex[edge[i].toi].siz)vertex[vertex[now].fsn].gfa=vertex[now].fsn,vertex[now].fsn=edge[i].toi;elsevertex[edge[i].toi].gfa=edge[i].toi;vertex[now].siz+=vertex[edge[i].toi].siz;}
}
void dfs1(int now)
{vertex[vertex[now].fsn].gfa=vertex[now].gfa;for(int i=vertex[now].son;i>-1;i=edge[i].nxt)dfs1(edge[i].toi);
}
int querylca(int u,int v)
{if(vertex[vertex[u].gfa].dep>vertex[vertex[v].gfa].dep)return querylca(v,u);if(vertex[u].gfa!=vertex[v].gfa)return querylca(u,vertex[vertex[v].gfa].fah);if(vertex[u].dep>vertex[v].dep)return v;return u;
}
void update(int now,int pow)
{for(int i=vertex[now].tos;i>-1;i=runner[i].nxts)if(pow>0&&opt[i]==-1)opt[i]=vertex[runner[i].s].dep+MAX_N,sum[opt[i]]+=pow;else if(pow<0&&opt[i]>-1)sum[opt[i]]+=pow,opt[i]=-1;for(int i=vertex[now].tot;i>-1;i=runner[i].nxtt)if(pow>0&&opt[i]==-1)opt[i]=(vertex[runner[i].lca].dep<<1)-vertex[runner[i].s].dep+MAX_N,sum[opt[i]]+=pow;else if(pow<0&&opt[i]>-1)sum[opt[i]]+=pow,opt[i]=-1;for(int i=vertex[now].son;i>-1;i=edge[i].nxt)if(edge[i].toi!=skp)update(edge[i].toi,pow);
}
void dfs(int now,bool kep)
{for(int i=vertex[now].son;i>-1;i=edge[i].nxt)if(edge[i].toi!=vertex[now].fsn)dfs(edge[i].toi,false);if(vertex[now].fsn>0)dfs(vertex[now].fsn,true);skp=vertex[now].fsn;update(now,1);ans[now]=sum[vertex[now].dep+w[now]+MAX_N]+sum[vertex[now].dep-w[now]+MAX_N];if(w[now]==0)ans[now]>>=1;skp=0;if(!kep)update(now,-1);for(int i=vertex[now].toa;i>-1;i=runner[i].nxtlca){if(opt[i]>-1)--sum[opt[i]],opt[i]=-1;if(runner[i].lsts>-1)runner[runner[i].lsts].nxts=runner[i].nxts;elsevertex[runner[i].s].tos=runner[i].nxts;if(runner[i].nxts>-1)runner[runner[i].nxts].lsts=runner[i].lsts;if(runner[i].lstt>-1)runner[runner[i].lstt].nxtt=runner[i].nxtt;elsevertex[runner[i].t].tot=runner[i].nxtt;if(runner[i].nxtt>-1)runner[runner[i].nxtt].lstt=runner[i].lstt;}
}
int main()
{freopen("running.in","r",stdin);freopen("running.out","w",stdout);scanf("%d %d",&n,&m);for(int i=0;i<=n;i++)opt[i]=vertex[i].son=vertex[i].toa=vertex[i].tos=vertex[i].tot=-1;for(int i=1;i<n;i++)scanf("%d %d",&edge[i<<1].toi,&edge[(i<<1)-1].toi),edge[i<<1].nxt=vertex[edge[(i<<1)-1].toi].son,edge[(i<<1)-1].nxt=vertex[edge[i<<1].toi].son,vertex[edge[(i<<1)-1].toi].son=i<<1,vertex[edge[i<<1].toi].son=(i<<1)-1;vertex[0].dep=-1;vertex[0].fsn=0;vertex[1].gfa=1;dfs0(1,0);dfs1(1);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<=m;i++)scanf("%d %d",&runner[i].s,&runner[i].t),runner[i].lca=querylca(runner[i].s,runner[i].t),runner[i].nxtlca=vertex[runner[i].lca].toa,runner[i].nxts=vertex[runner[i].s].tos,runner[i].nxtt=vertex[runner[i].t].tot,runner[i].lsts=runner[i].lstt=-1,runner[vertex[runner[i].s].tos].lsts=runner[vertex[runner[i].t].tot].lstt=i,vertex[runner[i].lca].toa=vertex[runner[i].s].tos=vertex[runner[i].t].tot=i;dfs(1,false);for(int i=1;i<=n;i++)printf("%d ",ans[i]);return 0;
}

提高组第一天第三题 换教室

动归。设 f[i][j][0] 为第 i 个时间段不申请换教室剩 j 次申请的最小数学期望,f[i][j][1] 为第 i 个时间段申请换教室剩 j 次申请的最小数学期望。则:

f[i][j][0] = min(f[i - 1][j][0]+ dist[c[i - 1]][c[i]],f[i - 1][j][1]+ (1 - k[i - 1]) * dist[c[i - 1]][c[i]]+ k[i - 1] * dist[d[i - 1]][c[i]])
f[i][j][1] = min(f[i - 1][j + 1][0]+ (1 - k[i]) * dist[c[i - 1]][c[i]]+ k[i] * dist[c[i - 1]][d[i]],f[i - 1][j + 1][1]+ (1 - k[i - 1]) * (1 - k[i]) * dist[c[i - 1]][c[i]]+ (1 - k[i - 1]) * k[i] * dist[c[i - 1]][d[i]]+ k[i - 1] * (1 - k[i]) * dist[d[i - 1]][c[i]]+ k[i - 1] * k[i] * dist[d[i - 1]][d[i]])

dist[i][j] 数组表示从点 i 到点 j 的最短路径长度,可由 Floyd 求得。100 分代码如下:

#include"stdio.h"
#include"string.h"
double f[2005][2005][2],k[2005];
int c[2005],d[2005],dist[305][305];
int main()
{freopen("classroom.in","r",stdin);freopen("classroom.out","w",stdout);double ans;int a,b,e,m,n,v,w;scanf("%d %d %d %d",&n,&m,&v,&e);for(int i=1;i<=n;i++)scanf("%d",&c[i]);for(int i=1;i<=n;i++)scanf("%d",&d[i]);for(int i=1;i<=n;i++)scanf("%lf",&k[i]);memset(dist,-1,sizeof(dist));for(int i=1;i<=v;i++)dist[i][i]=0;while(e--){scanf("%d %d %d",&a,&b,&w);if(dist[a][b]==-1||dist[a][b]>w)dist[a][b]=dist[b][a]=w;}for(int l=1;l<=v;l++)for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)if(dist[i][l]>-1&&dist[l][j]>-1&&(dist[i][j]==-1||dist[i][j]>dist[i][l]+dist[l][j]))dist[i][j]=dist[i][l]+dist[l][j];for(int i=0;i<=n+1;i++)for(int j=0;j<=m+1;j++)f[i][j][0]=f[i][j][1]=-1;f[1][m][0]=0;if(m>0)f[1][m-1][1]=0;for(int i=2;i<=n;i++)for(int j=m;j>=0;j--){if(f[i-1][j][0]>-1&&(f[i][j][0]==-1||f[i][j][0]>f[i-1][j][0]+dist[c[i-1]][c[i]]))f[i][j][0]=f[i-1][j][0]+dist[c[i-1]][c[i]];if(f[i-1][j][1]>-1&&(f[i][j][0]==-1||f[i][j][0]>f[i-1][j][1]+(1-k[i-1])*dist[c[i-1]][c[i]]+k[i-1]*dist[d[i-1]][c[i]]))f[i][j][0]=f[i-1][j][1]+(1-k[i-1])*dist[c[i-1]][c[i]]+k[i-1]*dist[d[i-1]][c[i]];if(f[i-1][j+1][0]>-1&&(f[i][j][1]==-1||f[i][j][1]>f[i-1][j+1][0]+(1-k[i])*dist[c[i-1]][c[i]]+k[i]*dist[c[i-1]][d[i]]))f[i][j][1]=f[i-1][j+1][0]+(1-k[i])*dist[c[i-1]][c[i]]+k[i]*dist[c[i-1]][d[i]];if(f[i-1][j+1][1]>-1&&(f[i][j][1]==-1||f[i][j][1]>f[i-1][j+1][1]+(1-k[i-1])*(1-k[i])*dist[c[i-1]][c[i]]+(1-k[i-1])*k[i]*dist[c[i-1]][d[i]]+k[i-1]*(1-k[i])*dist[d[i-1]][c[i]]+k[i-1]*k[i]*dist[d[i-1]][d[i]]))f[i][j][1]=f[i-1][j+1][1]+(1-k[i-1])*(1-k[i])*dist[c[i-1]][c[i]]+(1-k[i-1])*k[i]*dist[c[i-1]][d[i]]+k[i-1]*(1-k[i])*dist[d[i-1]][c[i]]+k[i-1]*k[i]*dist[d[i-1]][d[i]];}ans=f[n][m][0];for(int i=0;i<m;i++)if(f[n][i][0]>-1&&(f[n][i][1]==-1||f[n][i][0]<=f[n][i][1])&&(ans==-1||ans>f[n][i][0]))ans=f[n][i][0];else if(f[n][i][1]>-1&&(f[n][i][0]==-1||f[n][i][0]>f[n][i][1])&&(ans==-1||ans>f[n][i][1]))ans=f[n][i][1];printf("%.2lf",ans);return 0;
}

提高组第二天第一题 组合数问题

笔者看到此题的第一反应是找规律,接着随机了一个 k 后打印出 C(i, j) % k = 0 的点在二维平面上的投影,然后对着屏幕上的充满规律而又无从下手的点阵三角形不知道该如何是好。后来发现数据范围过小,直接预处理出二维和数组后即可过。100 分代码如下:

#include"stdio.h"
#include"string.h"
int c[2005][2005],sum[2005][2005];
int main()
{freopen("problem.in","r",stdin);freopen("problem.out","w",stdout);int k,m,n,t;scanf("%d %d",&t,&k);memset(c,-1,sizeof(c));memset(sum,0,sizeof(sum));for(int i=0;i<=2000;i++){c[i][0]=c[i][i]=1;for(int j=1;j<i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%k;if(i>0)for(int j=1;j<=2000;j++)sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+(c[i][j]==0);elsefor(int j=1;j<=2000;j++)sum[i][j]=sum[i][j-1]+(c[i][j]==0);}while(t--)scanf("%d %d",&n,&m),printf("%d\n",sum[n][m]);return 0;
}

提高组第二天第二题 蚯蚓

直接堆维护,记下每只蚯蚓出生时间和出生长度后懒惰更新,可得 65 分。对于懒惰更新还有一种方法,即将入堆的蚯蚓的长度看作从初始时刻不间断的增长而来。这便推出了满分做法,即我们可以发现这样处理后每次出堆和入堆的蚯蚓长度必然是不升的。于是,我们将堆改为队列,通过维护三个队列来实现修改和查询。一个初始队列记下初始蚯蚓长度,其他两个队列分别记下切成 p 和 1 - p 的蚯蚓在初始时刻的理论长度,易得三个队列都必然是不升的。每次切时取三个队列的队头的最大值删除,切成两段后计算出初始时刻理论长度插入后两个队列的队尾,查询时取三个队列的队头的最大值删除即可。这样,时间复杂度就做到了线性。100 分代码如下:

#include"stdio.h"
#include"stdlib.h"
#define judge(a,b,c) if(front##a<rear##a \&&(front##b>=rear##b||worm##a[front##a]>=worm##b[front##b]) \&&(front##c>=rear##c||worm##a[front##a]>=worm##c[front##c]))
#define cut(a,b,c) judge(a,b,c) \n=worm##a[front##a++]+(now-1)*q, \wormu[rearu]=(int)(n*(long long)u/v-now*q), \wormv[rearv++]=n-wormu[rearu++]-2*now*q;
#define chose(a,b,c) judge(a,b,c) \n=worm##a[front##a++]+m*q;
#define output \if(now==t) \printf("%d",n); \else if(now%t==0) \printf(" %d",n);
#define work(type) { \type(u,v,w) \else type(v,u,w) \else type(w,u,v) \output}
int wormu[7000005],wormv[7000005],wormw[100005];
int cmp(const void *p,const void *q)
{return *(int *)p<*(int *)q?1:-1;
}
int main()
{freopen("earthworm.in","r",stdin);freopen("earthworm.out","w",stdout);int frontu=0,frontv=0,frontw=0,m,n,q,rearu=0,rearv=0,rearw,t,u,v;scanf("%d %d %d %d %d %d",&rearw,&m,&q,&u,&v,&t);for(int i=0;i<rearw;i++)scanf("%d",&wormw[i]);qsort(wormw,rearw,sizeof(int),cmp);for(int now=1;now<=m;now++)work(cut)printf("\n");for(int now=1;frontu<rearu||frontv<rearv||frontw<rearw;now++)work(chose)return 0;
}

提高组第二天第三题 愤怒的小鸟

状压动归。考虑到鸟不会从极角序小的猪打到极角序大的猪,故可以先将猪按极角序排序并重新编号,让鸟先打极角序大的猪。设状态 f[i][j] 表示打完前 i 只猪且当前所有猪状态为 j 所需最少鸟数。由于猪数很少,故可以将状态压缩,用 2 ^ (i - 1) and j 表示第 i 只猪是否打过,=0 表示没打过,>0 表示打过。对于第 i 轮,预处理出所有经过的第一个猪(不论是否打过)为编号为 i 的猪的所有打法,依次进行状态转移即可。由于抛物线必过原点,所以确定第 i 头猪后只要再确定一头猪便可求出此时抛物线方程。注意有可能多条抛物线经过同一个猪,此时不能用算术加的方法计算猪的状态。为了解决这个问题,我们可以用位运算或的方法计算。由于官方数据没有刻意卡精度,所以不需要特别注意。具体过程详见代码。100 分代码如下:

#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#define abs(x) ((x)<0?-(x):(x))
#define equal 0.000001
#define Querya(x1,y1,x2,y2) (((x2)*(y1)-(x1)*(y2))/((x1)*(x2)*((x1)-(x2))))
#define Queryb(x1,y1,x2,y2) (((x1)*(x1)*(y2)-(x2)*(x2)*(y1))/((x1)*(x2)*((x1)-(x2))))
int f[524300],pg[20];
struct POINT
{double x,y;
}pig[20],tempg[20];
int cmp(const void *p,const void *q)
{return (*(POINT *)p).x*(*(POINT *)q).y>(*(POINT *)p).y*(*(POINT *)q).x?1:-1;
}
int main()
{freopen("angrybirds.in","r",stdin);freopen("angrybirds.out","w",stdout);bool flag;double tempa,tempb;int n,t,totalp;scanf("%d",&t);while(t--){scanf("%d %*d",&n);for(int i=0;i<n;i++)scanf("%lf %lf",&pig[i].x,&pig[i].y);qsort(pig,n,sizeof(POINT),cmp);memset(f,-1,sizeof(f));f[0]=0;for(int i=0;i<n;i++){pg[0]=1<<i;totalp=1;for(int j=i+1;j<n;j++)if(pig[i].x<pig[j].x&&pig[i].x*pig[j].y!=pig[i].y*pig[j].x){flag=true;tempa=Querya(pig[i].x,pig[i].y,pig[j].x,pig[j].y);tempb=Queryb(pig[i].x,pig[i].y,pig[j].x,pig[j].y);for(int k=1;k<totalp&&flag;k++)if(abs(tempa-tempg[k].x)<equal&&abs(tempb-tempg[k].y)<equal)pg[k]|=1<<j,flag=false;if(flag)pg[totalp]=1<<i|1<<j,tempg[totalp].x=tempa,tempg[totalp++].y=tempb;}for(int j=(1<<n)-1;j>=0;j--)if(f[j]>-1)for(int k=0;k<totalp;k++)if(f[j|pg[k]]==-1||f[j|pg[k]]>f[j]+1)f[j|pg[k]]=f[j]+1;}printf("%d\n",f[(1<<n)-1]);}return 0;
}

NOIP2016 略解相关推荐

  1. Golang 的 “omitempty” 关键字略解

    转载地址:Golang 的 "omitempty" 关键字略解 原文 :Golang 的 "omitempty" 关键字略解[1] 用法 熟悉 Golang 的 ...

  2. 《孙子略解》曹操注-2011

    [size=medium] 〈序〉 操闻上古弧矢之利,<论语>:「足兵.」<尚书>:「八政曰师.」<易>曰:「 师贞,丈人吉.」<诗>曰:「王赫斯怒,爰 ...

  3. 【Cylinder3D论文解读及代码略解】

    Cylinder3D论文解读及代码略解 论文解读 Abstract Introduction Related work 室内点云分割 室外点云分割 3D体素划分 Methodology(本文方法) C ...

  4. 正则化与L0、L1、L2范数略解

    机器学习模型需要拥有很好地泛化能力来适应训练集中没有出现过的新样本.在机器学习应用时,我们经常会遇到过度拟合(over-fitting)的问题,可能会导致训练出来的模型效果很差.接下来,我们将谈论的正 ...

  5. Dojo API略解续

    dojo.lang.string dojo.string.substituteParams 类似C#中的String.Format函数 %{name}要保证与传入的对象的名称大小写一致,否则会出异常 ...

  6. 类加载过程(时机)略解

    目录: java虚拟机汇总 class文件结构分析 1).class文件常量池中的常量项结构 2). 常用的属性表的集合 类加载过程<<== 现在位置 1).类加载器的原理以及实现 虚拟机 ...

  7. 各种抗锯齿模式略解:SSAA MSAA CSAA CFAA

    FSAA--Full Screen Anti-Aliasing的缩写,望文生义就是指全屏抗锯齿画面增强技术,用以缩小3D建模边缘锯齿形状,使得较低的分辨率拥有接近较高分辨率的画面表现. 关于3D建模和 ...

  8. Java8之lambda表达式略解

    一.什么是lambda表达式? Lambda 表达式,其实就是匿名函数.而函数其实就是功能(function),匿名函数,就是匿名的功能代码了,我们可以把 Lambda 表达式理解为是一段可以传递的代 ...

  9. 舞蹈链算法(DLX 算法)略解

    Another Blog DLX=Dancing Line X 之前学 DLX 时在网上看了好几篇博客,结合着几篇讲代码的.有图片的.说原理的,总算弄懂了.这里 DLX 是用来解决精确覆盖问题的算法, ...

最新文章

  1. jQuery DateTimePicker 日期和时间插件
  2. python读取大文件-python快速读取一个大文件内容(瞎猜)
  3. 【Groovy】编译时元编程 ( 编译 ASTTransformation | 打包 ASTTransformation 字节码文件 | 编译 Groovy 类同进行编译时处理 )
  4. ASP.NET Core托管运行Quartz.NET作业调度详解
  5. ubuntu 安装软件到一半被中断的解决办法
  6. php 把java list对象转成数组,java_JSON的String字符串与Java的List列表对象的相互转换,在前端: 1.如果json是List对象 - phpStudy...
  7. SAP License:SAP中的产量法折旧计算
  8. 如何安装Ruby(Windows)
  9. 南京理工大学本科毕业论文答辩PPT模板
  10. 神经网络的过拟合是什么,神经网络过拟合的表现
  11. IEC61850和IEC60870-6(TASE.2)的比较
  12. HTTP请求的TCP瓶颈分析
  13. 为什么我坚定看好分布式存储
  14. bat 实现笔记本键盘开关
  15. 作为程序员你应该会的软件
  16. 菜鸟入门--摄影术语
  17. π的值(已算到6086位)
  18. Mac 解决 ERROR launching ‘JD-GUI‘
  19. python编程价格_Python基础练习实例46(查询价格)
  20. 建立适当的索引(ZZ)

热门文章

  1. JavaScript 红宝书第4版上市啦!「文末送几本给大家」
  2. MySQL架构原理(七)集群架构和主从模式部署
  3. CS61B学习笔记——proj3 CS61BYoW的要求及实现
  4. 1 监督学习与非监督学习简介--机器学习基础理论入门
  5. 学籍信息管理系统c语言编程,学生学籍信息管理系统C语言设计.doc
  6. 游戏特效贴图的制作与应用
  7. Milon.MorFIX,myie2查找wkipedia的plugin
  8. 如何利用canvas画一个圆,并且填充颜色
  9. python爬虫进阶-每日一学(滑块拼图)
  10. Red Hat Enterprise Linux (RHEL) 8.5 发布(含下载)