7.28模拟和排序

这天苦逼的我只出了1题,现在看来其实都不是那样难

地址 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27454#overview

密码acmore

Problem A POJ 3125

Printer Queue

题目大意就是说有一系列的工作要做,但是如果工作队列中阿有比排在最前面的工作更重要的话,就将最前面的工作排在队列尾去,只有处理工作花时间,其他操作不花时间,问要处理第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

Parencodings

帮你给出每个右括号的左边的左括号数目,问每个右括号(包括自己)左边有多少个右括号

可以拿暴力枚举(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

Emag eht htiw Em Pleh

这个就不讲了

 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

Grandpa is Famous

这个就更水了,统计出现次数,排序输出第二大的

 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

An Old Stone Game

最初的确还不太会,听了别人说了用贪心的思想后,一心摸索着要将这棵树从叶子节点贪心到父节点,本来树的操作就不是太会,结果弄得特别复杂,看了渊哥的结题报告后,才明白其实可以用递归方法做,对每一个父节点,求出它所有子节点所需要的石头的个数,然后按照降序排序

上图中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 }

 

转载于:https://www.cnblogs.com/gj-Acit/p/3228889.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值