题目地址: http://codeforces.com/contest/330
这套题目都不难,主要看思维和反应能力
第一题:水题
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
typedef long long LL;
const int N=66;
const LL II=100000000;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
char s[12][12];
int vis[12][12];
int main()
{
int i,j,T;
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++)
scanf("%s",s[i]);
int sum=0;
for(i=0;i<n;i++)
{
int flag=0;
for(j=0;j<m;j++)
if(s[i][j]=='S')
{
flag=1;break;
}
if(flag==0)
{
for(j=0;j<m;j++)
{
if(s[i][j]=='.')
sum++;
s[i][j]='x';
}
}
}
for(j=0;j<m;j++)
{
int flag=0;
for(i=0;i<n;i++)
if(s[i][j]=='S')
{
flag=1;break;
}
if(flag==0)
{
for(i=0;i<n;i++)
{
if(s[i][j]=='.')
sum++;
s[i][j]='x';
}
}
}
printf("%d\n",sum);
}
return 0;
}
第二题:
由于题目给出了这个条件.开始的时候没注意,看了别人做的那么快,又看了一遍题目,果断发现之,
m<n/2,所以至少有一个点没有出现在上面,所以将所有的点与这个没有出现的点连起来即为答案。
开始的时候傻了10^3我开了111的数组,果断错了一次,哎……
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
int k[1111];
int main()
{
int i,j,n,m,flag,sum;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(k,0,sizeof(k));
for(i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
k[a]=k[b]=1;
}
int t;
for(i=1;i<=n;i++)
{
if(k[i]==0)
{
t=i;
break;
}
}
printf("%d\n",n-1);
for(i=1;i<=n;i++)
{
if(i==t) continue;
printf("%d %d\n",t,i);
}
}
return 0;
}
第三题:求每一行或每一列是不是都出现"."即可,因为至少是n个点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
char s[111][111];
int p[111][111];
int sum,n;
int main()
{
int i,j,m,flag;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%s",s[i]+1);
int sum1=0,sum2=0;
for(i=1;i<=n;i++)
{
flag=0;
for(j=1;j<=n;j++)
if(s[i][j]=='.')
{
flag=1;break;
}
if(flag)
sum1++;
}
for(j=1;j<=n;j++)
{
flag=0;
for(i=1;i<=n;i++)
if(s[i][j]=='.')
{
flag=1;break;
}
if(flag)
sum2++;
}
if(sum1!=n&&sum2!=n)
{
printf("-1\n");
continue;
}
if(sum1==n)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
if(s[i][j]=='.')
{
printf("%d %d\n",i,j);break;
}
}
continue;
}
if(sum2==n)
{
for(j=1;j<=n;j++)
{
for(i=1;i<=n;i++)
if(s[i][j]=='.')
{
printf("%d %d\n",i,j);break;
}
}
continue;
}
}
return 0;
}
第四题:给你一个地图,E代表出口,S代表你自己,T代表树不能经过,数字类比代表在这个地方有t个怪兽,
你和怪兽每一秒都可以移动,想要经过怪兽必须将其杀死,问你用最短的时间达到出口最多要打败多少个怪兽。
思路:从出口开始搜索,搜索到人最少步数,在这个步数内(包括),能有多少个怪兽也能达到出口,即为答案。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
typedef __int64 LL;
const int N=1005;
const LL II=1000000007;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
int n,m,bx,by,ex,ey;
bool vis[N][N];
char maps[1005][1005];
int t[4][2]={1,0,-1,0,0,1,0,-1};
int Max;
struct xh
{
int x,y;
int step;
}w,e;
void bfs()
{
int i,j,sum=0;
memset(vis,0,sizeof(vis));
vis[bx][by]=1;
queue<xh> q;
w.step=0;w.x=bx;w.y=by;
q.push(w);
while(!q.empty())
{
e=q.front();
q.pop();
if(e.step>=Max)//这个地方是即将要加上的,所以是大于等于
{
break;
}
for(i=0;i<4;i++)
{
w=e;
int x=w.x+t[i][0],y=w.y+t[i][1];
if(x>=0&&x<n&&y>=0&&y<m&&maps[x][y]!='T'&&vis[x][y]==0)
{
vis[x][y]=1;
w.step+=1;
w.x=x; w.y=y;
if(maps[x][y]=='S')
Max=w.step;
else
sum+=(maps[x][y]-'0');
q.push(w);
}
}
}
printf("%d\n",sum);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j;
for(i=0;i<n;i++)
{
scanf("%s",maps[i]);
for(j=0;j<m;j++)
if(maps[i][j]=='E')
{
bx=i;by=j;
}
else if(maps[i][j]=='S')
{
ex=i;ey=j;
}
}
Max=INF;
bfs();
}
return 0;
}
第五题:给一幅图,图中任意结点的度数至多为2。
让你重构一幅图,要求:图中节点和原来一样,边数数量也一样,任意节点度数至多为2.
思路:随机算法,随机m个点,连成m条边,判断每一条边是否在给定的图里面,在的话,继续随机,都不在,则满足题目要求,直接输出。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
typedef __int64 LL;
const int N=100005;
const LL II=1000000007;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
int n,m,ans;
int a[N];
vector<int> v[N];
void ACMer_xiaohao()
{
int i,j,k;
int tmp=0,flag=0;
for(i=1;i<=500;i++)//随机500次
{
int ok=1;
random_shuffle(a+1,a+n+1);
for(j=1;j<=m;j++)
{
int si=v[a[j]].size();
for(k=0;k<si;k++)
{
if(j==n) tmp=1;
else tmp=j+1;
if(v[a[j]][k]==a[tmp])
{
ok=0;
break;
}
}
}
if(ok)
{
flag=1;
for(j=1;j<=m;j++)
{
if(j==n) tmp=1;
else tmp=j+1;
printf("%d %d\n",a[j],a[tmp]);
}
break;
}
}
if(!flag)
printf("-1\n");
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j,c,b;
for(i=1;i<=n;i++)
{
v[i].clear();//每次清除
a[i]=i;
}
for(i=1;i<=m;i++)
{
scanf("%d%d",&c,&b);
v[c].push_back(b);
v[b].push_back(c);
}
ACMer_xiaohao();
}
return 0;
}