7.28模拟和排序
这天苦逼的我只出了1题,现在看来其实都不是那样难
地址 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27454#overview
密码acmore
Problem A POJ 3125
题目大意就是说有一系列的工作要做,但是如果工作队列中阿有比排在最前面的工作更重要的话,就将最前面的工作排在队列尾去,只有处理工作花时间,其他操作不花时间,问要处理第i个工作要多少时间
比较水:直接拿链表处理
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 struct node{int Pority,next;}ma[105]; 5 int thing[105]; 6 7 int cmp(int a,int b) 8 { 9 return b<a; 10 } 11 12 int main() 13 { 14 int T; 15 while(~scanf("%d", &T))while(T--) 16 { 17 int N,My; 18 scanf("%d%d",&N,&My); 19 int p,now = 0, Time = 0, index = 0; 20 for(int i=0;i<N;i++) 21 { 22 scanf("%d",&p); 23 thing[i] = ma[i].Pority = p; 24 ma[i].next = (i==N-1) ? 0 : i+1; 25 } 26 sort(thing, thing + N, cmp); 27 int pre = N-1; 28 while(1) 29 { 30 if(now == My && ma[now].Pority == thing[index]){Time++;break;} 31 if(ma[now].Pority == thing[index]) 32 { 33 Time++; 34 index ++; 35 ma[pre].next = ma[now].next; 36 } 37 pre = now; 38 now = ma[now].next; 39 } 40 printf("%d\n",Time); 41 } 42 return 0; 43 }
Problem B POJ 1068
帮你给出每个右括号的左边的左括号数目,问每个右括号(包括自己)左边有多少个右括号
可以拿暴力枚举(n<=20 =.=!),也可以用栈来模拟
思路键代码
1 /**************************************************** 2 思路就是吧没办法配对的左括号放在栈里, 3 如果有一个新的右括号,那他一定只能和栈顶的左括号配对 4 *****************************************************/ 5 #include <cstdio> 6 #include <stack> 7 using namespace std; 8 int ans[25], Case, N; 9 stack<int>Stack;//定义一个栈,放的是还没有配对的左括号 10 int main() 11 { 12 while(~scanf("%d", &Case))while(Case -- ) 13 { 14 int num = 0, a, pre = 0;//pre保存之前输入的数 15 scanf("%d", &N); 16 for(int i = 0; i < N; i ++ ) 17 { 18 scanf("%d", &a); 19 if(a != pre)//如果输入的不等于之前的数,表示有新的左括号 20 { 21 for(int j = pre; j < a; j ++ )//把新的左括号全部放进栈 22 { 23 Stack.push(1);//由于栈里的数表示这个左括号和与之对应的右括号之间的右括号数目 24 } //所以最开始默认为只有与其对应的那一个 25 ans[num] = Stack.top();//由于输入的数代表的是右括号,所以将与他相邻的左括号拿走 26 Stack.pop(); 27 if(!Stack.empty())Stack.top() += ans[num];//由于拿走了一个栈里的左括号, 28 num++; //也就是说新的栈顶左括号内部又多了之前括号里所拥有的右括号 29 pre = a; 30 } 31 else//输入的数等于之前的数,便是要和栈里的左括号配对 32 { 33 ans[num] = Stack.top(); 34 Stack.pop(); 35 if(!Stack.empty())Stack.top() += ans[num]; 36 num++; 37 } 38 } 39 for(int i = 0;i < num; i ++ ) 40 { 41 printf("%d%c", ans[i], (i == num-1) ? '\n':' '); 42 } 43 } 44 return 0; 45 }
Problem C POJ 2993
这个就不讲了
1 #include <stdio.h> 2 #include <string.h> 3 #include <ctype.h> 4 char ma[8][8]; 5 int vis[8][8]; 6 7 8 int main() 9 { 10 char str[100]; 11 int key =0; 12 memset(vis,0,sizeof(vis)); 13 while(key<2) 14 { 15 gets(str); 16 int p = 7; 17 while(str[p]) 18 { 19 if(str[p+3] ==',') 20 { 21 vis[7-(str[p+2] - '1')][str[p+1] - 'a'] = 1; 22 ma[7-(str[p+2] - '1')][str[p+1] - 'a'] = key==0 ? str[p]:tolower(str[p]); 23 p+=4; 24 } 25 else 26 { 27 vis[7-(str[p+1] - '1')][str[p] - 'a'] = 1; 28 ma[7-(str[p+1] - '1')][str[p] - 'a'] = key==0 ? 'P':'p'; 29 p+=3; 30 } 31 } 32 key++; 33 } 34 for(int i=0;i<8;i++) 35 { 36 printf("+---+---+---+---+---+---+---+---+\n"); 37 for(int j=0;j<8;j++) 38 { 39 printf("|"); 40 if(vis[i][j]){ 41 if((i+j)%2)printf(":%c:", ma[i][j]); 42 else printf(".%c.",ma[i][j]); 43 } 44 else{ 45 if((i+j)%2)printf(":::"); 46 else printf("..."); 47 } 48 } 49 printf("|\n"); 50 } 51 printf("+---+---+---+---+---+---+---+---+\n"); 52 return 0; 53 }
Problem D POJ 2092
这个就更水了,统计出现次数,排序输出第二大的
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 int N,M; 7 struct node{int index,num;}Per[10005]; 8 int Time[10005]; 9 int cmp(node a,node b) 10 { 11 if(a.num != b.num)return b.num<a.num; 12 return a.index < b.index; 13 } 14 15 int main() 16 { 17 while(scanf("%d%d", &N, &M) && (N||M)) 18 { 19 int a; 20 memset(Per, 0, sizeof(Per)); 21 memset(Time, 0, sizeof(Time)); 22 for(int i = 0;i < N;i ++ ) 23 { 24 for(int j = 0;j < M; j++) 25 { 26 scanf("%d", &a); 27 Time[a]++; 28 } 29 } 30 int num = 0; 31 for(int i=0;i<=10000;i++)if(Time[i]) 32 { 33 Per[num].index = i; 34 Per[num].num = Time[i]; 35 num++; 36 } 37 sort(Per, Per+10002, cmp); 38 int key = Per[1].num, p = 2; 39 printf("%d",Per[1].index); 40 while(Per[p].num == key) 41 { 42 printf(" %d", Per[p].index); 43 p++; 44 } 45 printf("\n"); 46 } 47 return 0; 48 }
Problem E POJ 1694
最初的确还不太会,听了别人说了用贪心的思想后,一心摸索着要将这棵树从叶子节点贪心到父节点,本来树的操作就不是太会,结果弄得特别复杂,看了渊哥的结题报告后,才明白其实可以用递归方法做,对每一个父节点,求出它所有子节点所需要的石头的个数,然后按照降序排序
上图中A,B,C的子节点个数分别为3,1,2个所以排序后也就是3,2,1那我们先把3填满,多出两个,由于后面的数都是<=3的,所以如果有等于3 的那所需要的总数+1,小于则填满当前,跳到下一个
键代码
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 int tree[205][205];//建一棵树,第一个是父节点编号,存放的是每一个字节点的编号 7 8 int cmp(int a,int b) 9 { 10 return a>b; 11 } 12 13 int solve(int n) 14 { 15 if(tree[n][0] == 0)//到了叶子节点,返回1 16 { 17 return 1; 18 } 19 int num[205] = {0}; 20 for(int i=1;i<=tree[n][0];i++)//递归求解每一个节点所需要的数目 21 { 22 num[i] = solve(tree[n][i]); 23 } 24 sort(num+1, num+tree[n][0],cmp);//将同一层次的节点按照所需要的个数按降序排序 25 int ans = num[1]; 26 for(int i=2;i<=tree[n][0];i++) 27 { 28 if(ans-i+1 < num[i]) ans++;//如果不能填满下一个节点的子节点,ans++ 29 } 30 return ans; 31 } 32 33 int main() 34 { 35 int Case; 36 while(~scanf("%d", &Case))while(Case--) 37 { 38 int N,index; 39 scanf("%d", &N); 40 for(int i=1;i<=N;i++) 41 { 42 scanf("%d", &index); 43 scanf("%d", &tree[index][0]); 44 for(int j=1;j<=tree[index][0];j++) 45 { 46 scanf("%d",&tree[index][j]); 47 } 48 } 49 printf("%d\n", solve(1)); 50 } 51 return 0; 52 }