普及组第一题 买铅笔

水题,连循环都不需要。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. oracle的sequence是什么,关于Oracle的序列(Sequence)使用内容是什么呢?
  2. C++ leetcode 26. 删除排序数组中的重复项 给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
  3. laravel controller
  4. 扫描文件夹_按下苹果手机这个键,立马变身成为扫描仪,你不会还不知道吧?...
  5. 初学者:如何使用虚拟PC将Windows 7安装到虚拟机
  6. C++ setprecision()用法
  7. 威纶通触摸屏如何打开并升级EB8000旧版本项目并更换触摸屏型号?
  8. php京东接口开发,技术文档
  9. aws篇12 搭建一个推流、读流、RTSP服务器
  10. 主流数据库优缺点以及性能分析
  11. java经典算法(五)---zws
  12. 常用软件过程模型-快速原型模型,快速原型模型有哪几种?各有何特点?
  13. 速率法和终点法的区别_两点法终点法速率法.doc
  14. 正交相机与透视相机的区别
  15. 2 PC 有它,你就够了!
  16. 【专升本计算机】经典Office 2003专升本复习题(Word、Excel、PowerPoint)
  17. 开心下单助手v1.0免费版
  18. 年度征文 | 回顾2022,展望2023(我难忘的2022,我憧憬的2023)
  19. 双足机器人课设报告_双足竞步机器人-智能步行者设计-技术报告
  20. ubuntu下安装lua和luarocks

热门文章

  1. C语言:实现一个函数itoa(int n,char s[]),将整数n这个数字转换为对应的字符串,保存到s中...
  2. slackware linux,seamonkey引起的rpm2tgz问题
  3. python实现二叉树非递归前中后序遍历
  4. oracle 导出身份证号_ORACLE对身份证号码处理相关的SQL汇总
  5. 【全套资料.zip下载】数电课设-多功能电子钟数字钟Multisim仿真设计【Multisim仿真+报告+讲解视频.zip下载】
  6. LabVIEW调用.so文件的方法
  7. 学哪种编程语言比较好?
  8. Logminer使用(追加日志模式)
  9. fis3 的安装过程
  10. 使用itextpdf编辑PDF