7月28号的题目:Printer Queue&&Parencodings&&Grandpa is Famous&&Emag eht htiw Em Pleh&&An Old Stone Game

                                                  Printer Queuehttp://acm.tzc.edu.cn/acmhome/problemdetail.do?method=showdetail&id=1044

这个题目我想我是我做过的题目中思路最清晰的,代码最简洁的吧。(题目较简单)

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<queue>//主要考察队列的应用
 5 using namespace std;
 6 bool comp1(int x,int y)
 7 {
 8     return x>y;
 9 }
10 int main()
11 {
12     int t,i,n,m,s,d,temp;
13     int a[105];
14     queue<int> Q;
15     scanf("%d",&t);
16     while(t--)
17     {
18         s=0;
19         scanf("%d%d",&n,&m);
20         for(i=0;i<n;i++)
21         {
22             scanf("%d",&a[i]);
23             Q.push(a[i]);
24             if(i==m)
25             d=i+1;
26         }
27         sort(a,a+n,comp1);
28         temp=Q.front();
29             Q.pop();
30         for(i=0;i<n;i++)
31         {
32             while(temp!=a[i])
33             {
34                 Q.push(temp);
35                 d--;
36              if(d==0)
37             {
38                 d=Q.size();
39             }
40             temp=Q.front();
41             Q.pop();
42             }
43             s++;
44             if(d==1)
45                 break;
46             d--;
47             temp=Q.front();
48             Q.pop();
49         }
50         printf("%d
",s);
51         while(!Q.empty())
52             Q.pop();
53 
54     }
55     return 0;
56 }

                                                         Parencodingshttp://poj.org/problem?id=1068

题意:

P-sequence:表示第i个右括号前面有多少个左括号                                

W-sequence:表示第i个右括号与自己的左括号匹配好时他们之间有多少个左括号(包括本身的那个左括号)
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<string.h>
 6 using namespace std;
 7 int main()
 8 {
 9     queue<int> Q;
10     int a[100],i,j,t,n,temp,d,s;
11     scanf("%d",&t);
12     while(t--)
13     {
14         d=0;
15         memset(a,0,sizeof(a));
16         scanf("%d",&n);
17         for(i=1;i<=n;i++)
18         {
19             scanf("%d",&a[i]);
20             for(j=0;j<a[i]-a[i-1];j++)
21                 Q.push(1);
22             Q.push(2);
23         }
24         for(i=1;i<=2*n;i++)
25         {
26             temp=Q.front();
27             Q.pop();
28             a[i]=temp;
29         }
30         for(i=1;i<=2*n;i++)
31         {
32             s=0;
33         if(a[i]==2)
34         {  d++;
35         if(d!=n)
36             {
37                 for(j=i-1;j>=1;j--)
38             {
39                 if(a[j]==-1)
40                     {s++;continue;}
41                 if(a[j]==1)
42                     {s++;a[j]=-1;
43                 printf("%d ",s);break;
44                     }
45             }
46             }
47         else{
48                 for(j=i-1;j>=1;j--)
49             {
50                 if(a[j]==-1)
51                     {s++;continue;}
52                 if(a[j]==1)
53                     {s++;a[j]=-1;
54                 printf("%d
",s);break;
55                     }
56             }
57 
58         }
59         }
60         }
61         }
62     return 0;
63 }//做个模型就A了(有点乱)
                       Grandpa is Famoushttp://poj.org/problem?id=2092
就是找出第二大的数:(注意的是排序和查找)
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 struct line
 6 {
 7     int w;
 8     int num;
 9 }a[10005];
10 bool comp1(line a,line b)
11 {
12     if(a.num>b.num)
13         return true;
14     else if(a.num==b.num)
15     {
16         if(a.w<b.w)
17             return true;
18     }
19     return false;
20 }
21 int main()
22 {
23     int i,j,n,m,k,MAX,t;
24     while(scanf("%d%d",&n,&m)!=EOF)
25     {
26         if(n==0&&m==0)
27             break;
28         for(i=1;i<=10000;i++)
29         {
30             a[i].w=i;
31             a[i].num=0;
32         }
33         for(i=1;i<=n;i++)
34             for(j=1;j<=m;j++)
35         {
36             scanf("%d",&t);
37            a[t].num++;
38         }
39         sort(a+1,a+9999,comp1);
40         MAX=a[1].num;
41         for(i=2;i<=10000;i++)
42         {
43             if(a[i].num<MAX)
44                 {MAX=a[i].num;
45                 break;}
46         }
47         for(j=i;j<=10000;j++)
48         {
49             if(a[j].num==MAX&&a[j+1].num==MAX)
50                 printf("%d ",a[j].w);
51             else if(a[j].num==MAX&&a[j+1].num!=MAX)
52                 printf("%d
",a[j].w);
53         }
54     }
55     return 0;
56 }
          Emag eht htiw Em Plehhttp://poj.org/problem?id=2993
主要
是理解题目意思:转化成国际象棋的形式(总共32个棋子)
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string>
 4 #include<string.h>
 5 #include<algorithm>
 6 using namespace std;
 7 int main()
 8 {
 9     int i,j,d1,e1,n,m;
10     char c[33]={'+','-','-','-','+','-','-','-','+','-','-','-','+','-','-','-','+','-','-','-','+','-','-','-','+','-','-','-','+','-','-','-','+'};
11     char d[33]={'|','.','.','.','|',':',':',':','|','.','.','.','|',':',':',':','|','.','.','.','|',':',':',':','|','.','.','.','|',':',':',':','|'};
12     char e[33]={'|',':',':',':','|','.','.','.','|',':',':',':','|','.','.','.','|',':',':',':','|','.','.','.','|',':',':',':','|','.','.','.','|'};
13     char a[1000],b[1000];
14     char k[20][40];
15     for(i=0;i<17;i++)
16         for(j=0;j<33;j++)
17     {
18         if(i%2==0)
19             k[i][j]=c[j];
20         else
21         {
22             if(i==1||i==5||i==9||i==13)
23                 k[i][j]=d[j];
24             else
25                 k[i][j]=e[j];
26         }
27     }
28     gets(a);
29     gets(b);//输入有空格的字符串用get()!
30     n=strlen(a);m=strlen(b);
31     for(i=7;i<50;i=i+4)
32     {
33         if(a[i]!='K'&&a[i]!='Q'&&a[i]!='R'&&a[i]!='B'&&a[i]!='N')
34                 break;
35         if(a[i]=='K'||a[i]=='Q'||a[i]=='R'||a[i]=='B'||a[i]=='N')
36          {d1=(a[i+1]-'a')*4+2;
37         e1=15-(a[i+2]-'1')*2;
38         k[e1][d1]=a[i];
39          }
40     }
41     for(j=i;j<n;j=j+3)
42     {
43         d1=(a[j]-'a')*4+2;
44         e1=15-(a[j+1]-'1')*2;
45         k[e1][d1]='P';//这里要注意大小写。
46     }
47     for(i=7;i<50;i=i+4)
48     {
49         if(b[i]!='K'&&b[i]!='Q'&&b[i]!='R'&&b[i]!='B'&&b[i]!='N')
50                 break;
51         if(b[i]=='K'||b[i]=='Q'||b[i]=='R'||b[i]=='B'||b[i]=='N')
52          {d1=(b[i+1]-'a')*4+2;
53         e1=15-(b[i+2]-'1')*2;
54         k[e1][d1]=b[i]+32;
55          }
56     }
57      for(j=i;j<m;j=j+3)
58     {
59         d1=(b[j]-'a')*4+2;
60         e1=15-(b[j+1]-'1')*2;
61         k[e1][d1]='p';//这里要注意大小写。
62     }
63     for(i=0;i<17;i++)
64         {for(j=0;j<33;j++)
65             printf("%c",k[i][j]);
66             printf("
");
67         }
68 
69     return 0;
70 }最后要注意棋子的数目(可以全部有,也可以全部没有)。

                                      An Old Stone Gamehttp://acm.tzc.edu.cn/acmhome/problemdetail.do?method=showdetail&id=2200

显然有递归来做的:

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 using namespace std;
 5 struct leaf
 6 {
 7      int child_num;
 8      int child[2000];
 9 }tree[2000];
10 bool cmp(int  a,int  b)
11 {
12      return a>b;
13 }
14 int min(int a,int b)
15 {
16      return a>b?b:a;
17 }
18 int solve(int id)
19 {
20      int i,j,result,node[2000];
21      if(!tree[id].child_num)
22      return 1;
23      for(i=0,j=0;i<tree[id].child_num;i++)
24      node[j++]=solve(tree[id].child[i]);//循环找此节点的石子数
25      sort(node,node+j,cmp);
26      result=node[0];
27      for(i=1;i<j;i++)
28      result+=node[i]-min(node[i],result-i);
29      return result;
30 
31 }
32 int main()
33 {
34      int id,node_num,i,j,t,n;
35      scanf("%d",&t);
36      while(t--)
37      {
38           scanf("%d",&n);
39           for(j=0;j<n;j++)
40           {
41                scanf("%d %d",&id,&node_num);
42           tree[id].child_num=node_num;
43           for(i=0;i<node_num;i++)
44           scanf("%d",&tree[id].child[i]);
45           }
46           printf("%d
",solve(1));
47      }
48 
49      return 0;
50 }

设所求结果用result来表示,我们要求的是以1为根的result,这个结果必定依赖于它的子节点的相关信息。这个信息会是什么呢?考虑一棵树的子孙是该树的子树。假设1的子孙分别为r1,r2,r3。那么r1,r2,r3,都是1的子树的根。假设以r1,r2,r3为根的上述结果分别为result1,result2,result3,显然它们之和一定能达到1上也能被放上石子的目的。那这个值是不是最小的呢?假设result1>=result2>=result3,我们用result1个石子让r1上放上了一个石子,此时我们剩余了result1-1个石子没有用,这些石子可以弥补result2,最终可能会得到一个更小的值(<=result1+result2+result3,通过对先前石子的重复利用)。如何安排这种弥补方式呢?

最大值优先。r1需要的石子result1最大,那么最终的结果必定result>=result1,然而最终只需在r1上放一个石子,留下了result1-1个石子。

那么r1 ,r2一共需要Result = result1+result2-min( result-1,result2 )个石子,其中min(result1-1,result2)被加了两次,所以要减掉一次。

这样r1,r2就合并成了一个节点,最少需要Result个石子,那么result=Result+result3-min(Result-2,result3)。最终得解。

 
 
原文地址:https://www.cnblogs.com/tt123/p/3222582.html