A - Cakeminator
题意: 怪兽吃cake一次吃一排或一行..但不能吃到草莓..问最多能吃掉多少cake...
思路:一个cake之所以吃不掉,是因为其同行的有草莓..同列的也有草莓..统计所有的cake..减去上述的cake既是答案...
Program:
#include<iostream> #include<stdio.h> #include<cmath> #include<queue> #include<stack> #include<set> #include<algorithm> using namespace std; char s[12][12]; int r,c; bool judge(int y,int x) { int i; bool f=false; for (i=1;i<=c;i++) if (s[y][i]=='S') f=true; for (i=1;i<=r;i++) if (s[i][x]=='S' && f) return false; return true; } int main() { int i,j,x,sum; while (~scanf("%d%d",&r,&c)) { gets(s[1]); for (i=1;i<=r;i++) gets(s[i]+1); sum=0; for (i=1;i<=r;i++) for (j=1;j<=c;j++) if (s[i][j]=='.' && judge(i,j)) sum++; printf("%d\n",sum); } return 0; }
题意: 有N个点..有些点 之间不能连线..问最少需要连接多少条边 ,使得这些点任意两个之间的距离<=2...并且输出这些边...
思路: 由于不合法的边个数M<N/2...那么必定有点是和其他任意点都可以连线的..以这个点作为父亲..其他点作为其孩子就行了..这样边数也明显是最小的..
Program:
#include<iostream> #include<stack> #include<queue> #include<stdio.h> #include<algorithm> #include<string.h> #include<cmath> #define ll long long #define oo 1000000007 #define MAXN 1005 using namespace std; int n,m; bool root[MAXN]; int main() { int i,x; while (~scanf("%d%d",&n,&m)) { memset(root,true,sizeof(root)); while (m--) { int x,y; scanf("%d%d",&x,&y); root[x]=root[y]=false; } for (x=1;x<=n;x++) if (root[x]) break; printf("%d\n",n-1); for (i=1;i<=n;i++) if (i!=x) printf("%d %d\n",i,x); } return 0; }
题意: 一个N*N的内充满了邪恶.要去除这些邪恶..每次可以选择一个不为'E'的点..将其同行的与同列的格子驱除邪恶..输出最小步数的方案..
思路: 如果能够成功驱除...必定每行都有一个清除点..或者每列都有一个清除点..查找判断下...就可以了.
Program:
#include<iostream> #include<stack> #include<queue> #include<stdio.h> #include<algorithm> #include<string.h> #include<cmath> #define ll long long #define oo 1000000007 #define MAXN 1005 using namespace std; char arc[MAXN][MAXN]; bool ok[2][MAXN]; int n; bool judge() { int i,j; memset(ok,false,sizeof(ok)); for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (arc[i][j]=='.') ok[0][i]=ok[1][j]=true; for (i=1;i<=n;i++) if (!ok[0][i]) break; if (i>n) { for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (arc[i][j]=='.') { printf("%d %d\n",i,j); break; } return true; } for (i=1;i<=n;i++) if (!ok[1][i]) break; if (i>n) { for (j=1;j<=n;j++) for (i=1;i<=n;i++) if (arc[i][j]=='.') { printf("%d %d\n",i,j); break; } return true; } return false; } int main() { int i; while (~scanf("%d",&n)) { for (i=1;i<=n;i++) scanf("%s",arc[i]+1); if (!judge()) printf("-1\n"); } return 0; }
题意: 在一个N*M的地图里..一个人要从S点走向E点..有树的地方是不能走的..又有些人来阻拦他..为了成功出去..他必须和能阻拦他的人打架..问最小的打架次数..
思路: 如果一个人能够阻拦道他..必定其道终点的时间小于等于他..so..从终点做一次BFS就可以了...
Program:
#include<iostream> #include<stack> #include<queue> #include<stdio.h> #include<algorithm> #include<string.h> #include<cmath> #define ll long long #define oo 1000000007 #define MAXN 1005 using namespace std; struct node { int x,y; }; queue<node> myqueue; char arc[MAXN][MAXN]; int n,m,dis[MAXN][MAXN],way[4][2]={{-1,0},{1,0},{0,-1},{0,1}},d[MAXN*MAXN],N[MAXN*MAXN]; void BFS(int y,int x) { node h,p; int i,DIS=oo,ans,num=0; memset(dis,0,sizeof(dis)); h.y=y,h.x=x; dis[h.y][h.x]=1; myqueue.push(h); while (!myqueue.empty()) { h=myqueue.front(); myqueue.pop(); if (arc[h.y][h.x]=='S') DIS=dis[h.y][h.x]; if (arc[h.y][h.x]>='1' && arc[h.y][h.x]<='9') d[++num]=dis[h.y][h.x],N[num]=arc[h.y][h.x]-'0'; for (i=0;i<4;i++) { p.y=h.y+way[i][0],p.x=h.x+way[i][1]; if (p.y && p.x && p.y<=n && p.x<=m && arc[p.y][p.x]!='T' && !dis[p.y][p.x]) { dis[p.y][p.x]=dis[h.y][h.x]+1; myqueue.push(p); } } } ans=0; for (i=1;i<=num;i++) if (d[i]<=DIS) ans+=N[i]; printf("%d\n",ans); return; } int main() { int i,j,dis,ans; while (~scanf("%d%d",&n,&m)) { for (i=1;i<=n;i++) scanf("%s",arc[i]+1); for (i=1;i<=n;i++) for (j=1;j<=m;j++) if (arc[i][j]=='E') BFS(i,j); } return 0; }
还不晓得做...貌似要用到随机化的东西....