Codeforces Round #192 (Div. 2)
题目地址: 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; }