赛间出了5道,赛后通过各种途径又弄了2道,感觉干不动了,还有3道真心不想干了。
第一题,是个大水题,算出总长,在算出两点之间的正着走的长度,在总长捡它,输出小的即可。
第二题,就是给你好多个字符串,任务是找出最小的不是它们子串的字符串,你的字符串大小判断是这样的a,b,c........z,aa,ab,ac.......az,ba,bb,bc.......bz,ca,......zz,aaa,........,反正我差不多就当数字做了,模拟进位,用string里的find判断子串,然后就ok了
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,num;
string s[40],a;
bool solve()
{
for(int i=0;i<n;i++)
{
if(s[i].find(a)!=-1)return false;
}
return true;
}
void add(int m,int jin)
{
if(jin==0)return;
if(m>0)
{
if(a[m-1]!='z')
{
a[m-1]+=1;
return;
}
else
{
a[m-1]='a';
add(m-1,1);
}
}
else
{
a="a"+a;
num++;
}
}
void go()
{
while(1)
{
if(solve())
{
cout<<a<<endl;
return ;
}
add(num,1);
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)cin>>s[i];
a="a";
num=1;
go();
return 0;
}
第三题,就是个并查集的题,不难,设一个f数组记录父子关系,r数组记录语言对应的人,下面拿第一组数据为例说明下
5 5 1 2 2 2 3 2 3 4 2 4 5 1 5第一行是代表5个人,5语言
第一个人会2语言,由于2在之前数据没人会(这里这是第一个数据),让r[2]=1;
第二个人会2,3语言,应为2语言第一个人会(r[2]=1)所以合并1,2俩人,f[2]=1了,3语言之前没人会,让r[3]=2;
。。。。。。(之后就这样依次类推)
最后只要看n个人分成了几摞就可以了,就是n个人f[x]=x的个数;
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m,n,num,yu,ans,sum;
int f[105],r[105];
int find(int i)
{
if(f[i]==i)return i;
else return find(f[i]);
}
void un(int a,int b)
{
int x=find(a);
int y=find(b);
f[x]=y;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
sum=0;
for(int i=1;i<=n;i++)f[i]=i;
memset(r,0,sizeof(r));
for(int i=1;i<=n;i++)
{
scanf("%d",&num);
if(num)sum=1;
for(int j=0;j<num;j++)
{
scanf("%d",&yu);
if(r[yu]==0)r[yu]=i;
else un(i,r[yu]);
}
}
if(sum==0)
{
cout<<n<<endl;
continue;
}
ans=0;
for(int i=1;i<=n;i++)
{
if(f[i]==i)ans++;
}
cout<<ans-1<<endl;
}
return 0;
}
第四题,自由发挥度很大啊,乱搞之。
题目意思是要n个点,这n点只能构成最多m边凸边形,输出符合的n个点就可以,只要符合就可以,无固定答案。
一开始是搞圆,外圆上均匀去m点,内圆上均匀取剩下的点,开始时3点共线,改写了下,不共线了但答案错误。
借鉴了网上的方法,用的x正半轴方向二次函数,y=x^2上面取m点,y=-x^2去剩下的点,在让上面下面的点距离拉大,上面的+一个大数,下面-大数。神了
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int m,n,a,b;
scanf("%d%d",&n,&m);
if(m==3&&n>4)
{
cout<<-1<<endl;
}
else
{
for(int i=1;i<=m;i++)
{
cout<<i<<" "<<1000000+i*i<<endl;
}
n-=m;
for(int i=1;i<=n;i++)
{
cout<<i<<" "<<-1000000-i*i<<endl;
}
}
return 0;
}
第五题,。。。。
第六题,水题,只要处理奇数次的就可以了,偶数次对结果不影响。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
int a[5][5];
int b[5][5];
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
scanf("%d",&a[i][j]);
b[i][j]=1;
}
}
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
if(a[i][j]%2==1)
{
b[i][j]=-b[i][j];
b[i-1][j]=-b[i-1][j];
b[i+1][j]=-b[i+1][j];
b[i][j-1]=-b[i][j-1];
b[i][j+1]=-b[i][j+1];
}
}
}
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
if(b[i][j]==1)cout<<1;
else cout<<0;
}
cout<<endl;
}
return 0;
}
第七题,有m*n的格子,有黑有白,要判断是否任意两黑格间能到达对方,只经过其他黑格并且转弯次数只能最多1次。这题由于数据不是很大,枚举任意俩黑格,全部验证一遍即可。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m,n;
char a[55][55];
bool hen(int x1,int y1,int x2,int y2)
{
if(x1>x2)
{
for(int i=x1; i>=x2; i--)
{
if(a[i][y1]!='B')return false;
}
for(int i=y1; i<=y2; i++)
{
if(a[x2][i]!='B')return false;
}
}
else
{
for(int i=x1; i<=x2; i++)
{
if(a[i][y1]!='B')return false;
}
for(int i=y1; i<=y2; i++)
{
if(a[x2][i]!='B')return false;
}
}
return true;
}
bool shu(int x1,int y1,int x2,int y2)
{
for(int i=y1; i<=y2; i++)
{
if(a[x1][i]!='B')return false;
}
if(x1>x2)
{
for(int i=x1; i>=x2; i--)
{
if(a[i][y2]!='B')return false;
}
}
else
{
for(int i=x1; i<=x2; i++)
{
if(a[i][y2]!='B')return false;
}
}
return true;
}
bool go()
{
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(a[i][j]=='B')
{
for(int x=i; x<m; x++)
{
for(int y=0; y<n; y++)
{
if(a[x][y]=='B')
{
if(hen(i,j,x,y)||shu(i,j,x,y))continue;
else return false;
}
}
}
}
}
}
return true;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
//getchar();
for(int i=0; i<m; i++)
{
scanf("%s",&a[i]);
//scanf("%c",&a[i][j]);
//getchar();
}
if(go())cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
第八题,开始时想麻烦了,其实不难。
意思是,给你n个数和k,要你从中取数,去了x就不能取x*k,问做多能取几个。思路先排序,然后从头到尾遍历,第一个肯定取,将第一个数k倍的标记代表不能取它了,然后以后的数先判断是否被标记了,被标记则跳过,没被标记则取,并标记它的k倍,就ok了。
#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
long long int a[100005];
using namespace std;
int main()
{
int n,k,ans;
while(scanf("%d%d",&n,&k)!=EOF){
map<long long int,int >p;
ans=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
for(int i=0;i<n;i++)
{
if(p[a[i]]==0)
{
ans++;
p[k*a[i]]=1;
}
}
cout<<ans<<endl;}
return 0;
}
第九题,。。。
第十题,。。。