http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2348&cid=1232
题意:
有两个磁盘,第一个磁盘有n个安装包,第二个磁盘有m个安装包。有些安装包的安装依赖于其他安装包的安装,即如果x依赖与y,那么包y必须在包x之前安装,每次可以插入这两张磁盘中的一张去安装一些包,求以最小的交换次数安装好所有的包,保证依赖关系不存在环,开始插入和最后取出都算一次交换,初始是磁盘设备是为空的。
解题思路:做两次拓扑排序即可,分别代表先插第一个磁盘和第二个磁盘的交换次数,然后取最小值。
#include <stdio.h> #include <string.h> #include <algorithm> #include <vector> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; int n,m,k; vector <int> edge[100010];//保存依赖该点的点 queue <int> que[2]; int in[100010],deg[100010];//保存入度 int ans; void toposort(int kind) { //用两个队列分别维护两个磁盘,假如先对第一个磁盘拓扑排序,那么交换次数增1是在第一个队列为空时, //因为这时就要拔掉第一个磁盘,插入第二个磁盘。当两个队列都为空时,拓扑排序完成。 while(!que[0].empty()) que[0].pop(); while(!que[1].empty()) que[1].pop(); int cnt = 0; for(int i = 1; i <= n+m; i++) { if(deg[i] == 0) //入度为0的点全部进队列 { if(i <= n) que[0].push(i); else que[1].push(i); } } while(!que[0].empty() || !que[1].empty()) { while(!que[kind].empty()) { int u = que[kind].front(); que[kind].pop(); for(int i = 0; i < (int)edge[u].size(); i++) { int v = edge[u][i]; deg[v]--; if(deg[v] == 0) { if( v <= n) que[0].push(v); else que[1].push(v); } } }//当前队列为空,说明一个磁盘中的包安装完了,应换另一个磁盘,所以增1。 kind = kind^1; cnt++; } ans = min(ans,cnt); } int main() { while(~scanf("%d %d %d",&n,&m,&k)) { if(n == 0 && m == 0 && k == 0) break; for(int i = 1; i <= n+m; i++) edge[i].clear(); memset(in,0,sizeof(in)); memset(deg,0,sizeof(deg)); int u,v; while(k--) { scanf("%d %d",&u,&v); edge[v].push_back(u); in[u]++; } ans = INF; for(int i = 1; i <= n+m; i++) deg[i] = in[i]; toposort(0);//假如先插入第一个磁盘,进行拓扑排序。 for(int i = 1; i <= n+m; i++) deg[i] = in[i]; toposort(1);//假如先插入第二个磁盘,进行拓扑排序。 printf("%d\n",ans+1); } return 0; }
#include <stdio.h> #include <string.h> #include <cmath> using namespace std; int pow2[30] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144, 524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728}; int main() { char str[5]; while(~scanf("%s",str)) { if(strcmp(str,"00e0") == 0) break; if(strcmp(str,"01e0") == 0) { printf("1\n"); continue; } int x,y,z; x = str[0]-'0'; y = str[1]-'0'; z = str[3]-'0'; int mul = (int)pow(10,z); int num = x*mul*10 + y*mul; //printf("%d\n",num); if(num % 2 == 0) { if((num & (num-1)) == 0) { printf("1\n"); continue; } for(int i = 0; i < 28; i++) { if(pow2[i] < num && pow2[i+1] > num) { printf("%d\n",(num-pow2[i])*2+1); break; } } } else { num = num-1; if((num & (num-1)) == 0) { printf("3\n"); continue; } for(int i = 0; i < 28; i++) { if(pow2[i] < num && pow2[i+1] > num) { printf("%d\n",(num-pow2[i])*2+3); break; } } } } return 0; } /*int main() { for(int i = 0; i <= 27; i++) printf("%d\n",(int)pow(2,i)); }*/http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2352&cid=1232
#include <stdio.h> #include <string.h> char s[1010]; int num[1010]; int main() { while(gets(s)) { int len = strlen(s); for(int i = 0; i < len; i++) { num[i] = 0; int cnt = 0; for(int j = i; j < len; j++) { if(s[i] == s[j]) cnt++; else break; } num[i] = cnt; } int flag = 1; for(int i = 0; i < len;) { if(num[i] == 1) { if(flag) { printf("1"); flag = 0; } if(s[i] == '1') printf("%c%c",s[i],s[i]); else printf("%c",s[i]); i++; } else { if(flag == 0) { printf("1"); flag = 1; } if(num[i] <= 9) { printf("%d%c",num[i],s[i]); i += num[i]; } else { printf("9%c",s[i]); i += 9; } } } if(!flag) printf("1"); printf("\n"); } return 0; }