A.Phone Number
一水,赛后听Triple_Sb是用字典树做的,逗逼了。。。
就简单的strncmp()函数的应用。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
char str[1010][100];
int main()
{
int t,i,j,n;
while(~scanf("%d",&n)&&n)
{
int f=0;
for(i=0;i<n;i++)
scanf("%s",str[i]);
for(i=0;i<n;i++)
{
int li=strlen(str[i]);
for(j=0;j<n;j++)
{
if(i==j)continue;
int lj=strlen(str[j]);
int l=min(li,lj);
if(strncmp(str[i],str[j],l)==0)
{
f=1;
break;
}
}
}
if(f)printf("NO\n");
else printf("YES\n");
}
return 0;
}
C.Hello World!
赛中这题不是我做的,Hypo+wz做了,先贴他们的代码,回头补补。。。
回头写写,WA了。。。下了数据测试下,没有错误。。。
最后在Ball的测试数据下才发现自己的排序出问题了。。。
逗了,用了很久的sort瞬间都不会了。。。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
struct node
{
int x,y,t;
} num[10010],pp[10010];
int cmp(node a,node b)
{
if(a.x!=b.x)
return a.x<b.x;
else
return a.y<b.y;
}
int cmp1(node a,node b)
{
return a.t<b.t;
}
int main()
{
int t,i,j,n,k=1,f;
while(~scanf("%d",&n)&&n)
{
for(i=0; i<n; i++)
{
scanf("%d%d",&num[i].x,&num[i].y);
num[i].t=i;
}
sort(num,num+n,cmp);
printf("Case %d:\n",k++);
int cnt=0;
for(i=0; i<n; i++)
{
f=0;
for(j=i+1; j<n; j++)
{
if(num[j].x>num[i].x&&num[j].y>num[i].y)
{
pp[cnt].x=num[j].x;
pp[cnt].y=num[j].y;
pp[cnt++].t=num[i].t;
f=1;
break;
}
}
if(f==0)
{
pp[cnt].x=-1;
pp[cnt].t=num[i].t;
pp[cnt++].y=-1;
}
}
sort(pp,pp+cnt,cmp1);
for(i=0;i<cnt;i++)
printf("%d %d\n",pp[i].x,pp[i].y);
printf("\n");
}
return 0;
}
D.Greatest Number
比赛这题我一看,很像背包的题目,要是背包就不会了,交给队友wz去想,比赛结束也没能A了,赛后找了题解,原来可以暴力出来,普通暴力是不行的,任意小于四个数相加,数据范围1000,也就是开1000*1000*1000*1000,没办法存下来,但是可以存下任意两个数的和,然后巧妙地在暴力二分出小于m的最大数。。。#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string.h>
using namespace std;
int num[10100000];
int main()
{
int n,m,i,j,t,k,kk=1;
//freopen("greatest.in","r",stdin);
while(~scanf("%d%d",&n,&m)&&n+m)
{
memset(num,0,sizeof(num));
j=1;
num[0]=0;//0个数相加
for(i=1; i<=n; i++)
{
scanf("%d",&t);
if(t>m)continue;
num[j++]=t;//1个数相加
}
k=j;
n=j;
for(i=1; i<n; i++)
{
for(j=i; j<n; j++)
{
if(num[i]+num[j]<=m)
{
num[k++]=num[i]+num[j];//两个数相加
}
}
}
n=k;
sort(num,num+n);
int r=n-1,u=n-1,l,maxx=0,f=0;
for(i=0; i<n; i++)
{
l=i;//每次选一个数进行二分查找小于m的数
f=0;
while(l<=r)
{
int mid=(l+r)/2;
int key=num[i]+num[mid];
if(key==m)//如果存在m
{
maxx=m;
f=1;
break;
}
else if(key>m)//如果大于m,缩小范围查找
{
r=mid-1;
}
else//如果小于m
{
l=mid+1;
if(maxx<key)
{
maxx=key;
//u=mid;
}
}
}
if(f)break;
//r=u;
r=n-1;
}
printf("Case %d: %d\n\n",kk++,maxx);
}
return 0;
}
F.Emergency
这题就是求有向单源最短路,题目不是我读的,wz读完题跟我说是最小生成树,一听,我就自己单干,先敲个最小生成树的模板,然后一看就不对,明明是最短路问题,赶紧写DIJKstra算法,由于只能走标记的点,wz跟我说了一个技巧,听好使的,结果超时了,一想不对,又没考虑时间复杂度的问题。。。
在一旁想了一会,才发现这题曾经做过。。。冏。。。
换了flody算法。。。结果WA,手残了,少了Case和回车。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#define inf 10000000
using namespace std;
int n,m;
int mmap[1060][1060];
int va[1060];
void flody(int k)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(mmap[i][j]>mmap[i][k]+mmap[k][j])
mmap[i][j]=mmap[i][k]+mmap[k][j];
}
int main()
{
int q,i,j,a,b,c,p,lp,s,e,k=1;
while(~scanf("%d%d%d",&n,&m,&q))
{
memset(va,0,sizeof(va));
if(!n&&!m&&!q)break;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
mmap[i][j]=inf;
mmap[i][i]=0;
}
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(c<mmap[a][b])
mmap[a][b]=c;
}
printf("Case %d:\n",k++);
while(q--)
{
scanf("%d",&p);
if(p==0)
{
scanf("%d",&lp);
if(va[lp])
printf("City %d is already recaptured.\n",lp);
else
flody(lp);
va[lp]=1;
}
else if(p==1)
{
scanf("%d%d",&s,&e);
if(!va[s]||!va[e])
printf("City %d or %d is not available.\n",s,e);
else
{
int d=mmap[s][e];
if(d==inf)
printf("No such path.\n");
else
printf("%d\n",d);
}
}
}
printf("\n");
}
return 0;
}
G.Shopping
一看又是签到题。。。好像还可以直接(最大-最小)/2
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int num[1000100];
int main()
{
int t,i,j,n;
while(~scanf("%d",&n)&&n)
{
memset(num,0,sizeof(num));
int sum=0;
for(i=0;i<n;i++)
scanf("%d",&num[i]);
sort(num,num+n);
for(i=1;i<n;i++)
{
sum+=num[i]-num[i-1];
}
sum+=abs(num[n-1]-num[0]);
printf("%d\n",sum);
}
return 0;
}
I.Balloons
没读题,就看到测试数据,一个裸DFS。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
char mmap[200][200];
int dx4[]={-1,0,1,0};
int dy4[]={0,1,0,-1};
int dx8[]={-1,0,1,-1,1,-1,0,1};
int dy8[]={-1,-1,-1,0,0,1,1,1};
int vis4[200][200];
int vis8[200][200];
int n;
void s_dfs(int s,int e)
{
for(int i=0;i<4;i++)
{
int x=s+dx4[i];
int y=e+dy4[i];
if(x>=0&&x<n&&y>=0&&y<n&&!vis4[x][y]&&mmap[x][y]!='0')
{
vis4[x][y]=1;
s_dfs(x,y);
}
}
}
void k_dfs(int s,int e)
{
for(int i=0;i<8;i++)
{
int x=s+dx8[i];
int y=e+dy8[i];
if(x>=0&&x<n&&y>=0&&y<n&&!vis8[x][y]&&mmap[x][y]!='0')
{
vis8[x][y]=1;
k_dfs(x,y);
}
}
}
int main()
{
int i,j,k=1;
while(~scanf("%d",&n)&&n)
{
int cnt4=0;
int cnt8=0;
memset(vis4,0,sizeof(vis4));
memset(vis8,0,sizeof(vis8));
memset(mmap,0,sizeof(mmap));
for(i=0;i<n;i++)
scanf("%s",mmap[i]);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
if(mmap[i][j]=='1'&&!vis4[i][j])
{
vis4[i][j]=1;
s_dfs(i,j);
cnt4++;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
if(mmap[i][j]=='1'&&!vis8[i][j])
{
vis8[i][j]=1;
k_dfs(i,j);
cnt8++;
}
}
printf("Case %d: %d %d\n",k++,cnt4,cnt8);
printf("\n");
}
return 0;
}
赛后总结
组队赛还是不够好,在我看来理想的组队时先队友A自己的题,保证自己的出题速度和效率,一道题至少要有两个人读题。。。而且不应该在比赛前期的时候,两个人做一题,这样出题没效率。。。还有就是坚持到最后,这一次我们队确实输在这一点上,还有一个小时的时候,就放弃了,有两题都卡TLE了,就没人去解。。。而Triple_Sb的soring一直到最后半小时的时候给A了一题,反超我们队。。。
自己在做题读题方便还是不行,手残了好几次,贡献了罚时。。。不能一直读完一题。。。其实还是英语的问题。。。基本不怎么和队友合作。。。