暑期 结题报告(选)

1):杭电acm 1022

Train Problem I

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 26466    Accepted Submission(s): 10000

Problem Description

As the new term comes, the Ignatius Train Station is very busy nowadays. A lot of student want to get back to school by train(because the trains in the Ignatius Train Station is the fastest all over the world ^v^). But here comes a problem, there is only one railway where all the trains stop. So all the trains come in from one side and get out from the other side. For this problem, if train A gets into the railway first, and then train B gets into the railway before train A leaves, train A can't leave until train B leaves. The pictures below figure out the problem. Now the problem for you is, there are at most 9 trains in the station, all the trains has an ID(numbered from 1 to n), the trains get into the railway in an order O1, your task is to determine whether the trains can get out in an order O2.

 

 

Input

The input contains several test cases. Each test case consists of an integer, the number of trains, and two strings, the order of the trains come in:O1, and the order of the trains leave:O2. The input is terminated by the end of file. More details in the Sample Input.

 

 

Output

The output contains a string "No." if you can't exchange O2 to O1, or you should output a line contains "Yes.", and then output your way in exchanging the order(you should output "in" for a train getting into the railway, and "out" for a train getting out of the railway). Print a line contains "FINISH" after each test case. More details in the Sample Output.

 

 

Sample Input

3 123 321

3 123 312

 

 

Sample Output

Yes.

in

in

in

out

out

out

FINISH

No.

FINISH

 

Hint

Hint

 

For the first Sample Input, we let train 1 get in, then train 2 and train 3.

So now train 3 is at the top of the railway, so train 3 can leave first, then train 2 and train 1.

In the second Sample input, we should let train 3 leave first, so we have to let train 1 get in, then train 2 and train 3.

Now we can let train 3 leave.

But after that we can't let train 1 leave before train 2, because train 2 is at the top of the railway at the moment.

So we output "No.".

 

 

Author

Ignatius.L

 

题目大意:

   火车要依次进站,依次出站,即后进站的车要先出。

题意分析:

此题是先进后出问题,是典型的栈用例,因此就用栈来解决。

代码:

#include<stdio.h>

#include<string.h>

#include<stack>//调用栈函数

using namespace std;

int main()

{

    int n, i, j, k, flag[50];

    char s1[15], s2[15];//存放进出站火车序号

    stack <char> s;//定义栈

    while(~scanf("%d %s%s",&n,s1,s2))

    {   

        while(!s.empty())  s.pop(); //非空时清空栈; 

        memset(flag,-1,sizeof(flag));//flag 全置为 -1; 

        j = k = 0;

        for(i = 0; i < n; i++)

        {

            s.push(s1[i]);//s1依次入栈

            flag[k++] = 1;//标记入栈; 

            while(!s.empty() && s.top() == s2[j])

            {

                flag[k++] = 0;//标记出栈于s2相同,说明是可行的; 

                s.pop();//清栈顶元素

                j++;

            }

        }

        if(j == n)//j==n说明进站与出站序列号相对应,是可行的

        {

            printf("Yes.\n");

            for(i = 0; i < k; i++)

            {

                if(flag[i])

                    printf("in\n");

                else

                    printf("out\n");

            }

        }

        else

            printf("No.\n");

        printf("FINISH\n");

    }

    return 0;

}

 

解题分析:

   此题是很典型的栈,最开始刚学不太会用,就想能不能换一种方法,于是就用各种试,其中我觉得可行又简单的是判断一下两者是否对称,即出栈车序列倒叙与入站序列比较是否一致,然而总是错》给出错误代码如下:

#include <stdio.h>

#include <string.h>

 

char a[11000],b[11000],s[11000];

 

int main()

{

    int i,j,c,k;

    while(scanf("%d",&c)!=EOF)

    {

            getchar();

            scanf("%s",a);

            scanf("%s",b);//输入两序列

            k=0;

            for(j=strlen(b)-1;j>=0;j--)

            {

                s[j]=b[k++];//将出战序列倒叙给s

            }

            if(strcmp(a,s)==0)//比较入站序列是否等于s

            {

                printf("Yes.\n");

                for(i=0;i<c;i++)

                printf("in\n");

                for(i=0;i<c;i++)

                printf("out\n");

            }

            else

            {

                printf("No.\n");

            }

        printf("FINISH\n");

    }

}

然后,又进行了改进,将其各种输入输出进行改变,但仍然错误,目前为止我确实不清楚哪里错,感觉思路是没什么问题啊!于是相当固执的错了9次之多。最后网上查找没发现用我这种思路的,没办法,先ac了再说吧!于是经过一天的研究,查资料在借鉴网上,书上,最后就有了上边正确的代码,但我有空一定会再好好看看研究一下这个错的到底哪错了,毕竟不甘心,而且测试并未发现有错!!!

 

(2)杭电acm 1050

Moving Tables

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 24614    Accepted Submission(s): 8137

Problem Description

The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in the following figure. 



The floor has 200 rooms each on the north side and south side along the corridor. Recently the Company made a plan to reform its system. The reform includes moving a lot of tables between rooms. Because the corridor is narrow and all the tables are big, only one table can pass through the corridor. Some plan is needed to make the moving efficient. The manager figured out the following plan: Moving a table from a room to another room can be done within 10 minutes. When moving a table from room i to room j, the part of the corridor between the front of room i and the front of room j is used. So, during each 10 minutes, several moving between two rooms not sharing the same part of the corridor will be done simultaneously. To make it clear the manager illustrated the possible cases and impossible cases of simultaneous moving. 



For each room, at most one table will be either moved in or moved out. Now, the manager seeks out a method to minimize the time to move all the tables. Your job is to write a program to solve the manager’s problem.

 

 

Input

The input consists of T test cases. The number of test cases ) (T is given in the first line of the input. Each test case begins with a line containing an integer N , 1<=N<=200 , that represents the number of tables to move. Each of the following N lines contains two positive integers s and t, representing that a table is to move from room number s to room number t (each room number appears at most once in the N lines). From the N+3-rd line, the remaining test cases are listed in the same manner as above.

 

 

Output

The output should contain the minimum time in minutes to complete the moving, one per line.

 

 

Sample Input

10 20 

30 40 

50 60 

70 80 

1 3 

2 200 

10 100 

20 80 

30 50 

 

 

Sample Output

10

20

30

 

 

Source

Asia 2001, Taejon (South Korea) 

 

 

题目大意:

   此题大意为,要搬桌子如图的一条走廊两边的房间标号,每次走廊同一段只能有一张桌子通过,搬一张需10分钟给出要搬的桌子起始与终止位置问最短要多久搬完。

题目分析:

不难看出,这个是可以用贪心解的,也可以用另一种思想,就是看那一段经过最多,既是要求的结果。

代码:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

int room[450];

 

int cmp(const void *a,const void *b)

{

    return *(int *)b-*(int *)a;

}

int main()

{

    int t,n,i,j,k,from,to;

    while(scanf("%d",&t)!=EOF)

    {

        

        for(i=0;i<t;i++)

        {

            memset(room,0,sizeof(room));//清空编号

            scanf("%d",&n);

            for(j=0;j<n;j++)

            {

                scanf("%d%d",&from,&to);//输入起始终止位置

                if(from>to)//避免重复了一段走廊

                {

                    int c;

                    c=from;

                    from=to;

                    to=c;

                }

                if(from%2==0)

                {

                    room[from-1]++;

                }

                if(to&2==1)//起始为偶数,终值为奇数时要将起始终点单独计算,否则会少算的

                {

                    room[to+1]++;

                }

                for(k=from;k<=to;k++)//依次计算对应走廊段走的次数

                {

                    room[k]++;

                }

            }

            qsort(room,410,sizeof(room[0]),cmp);//排序后找出最大值

            printf("%d\n",room[0]*10);

        }

    }

}

解题分析:

   刚开始,我是想用贪心的,找出每次尽可能多的同时移动然而,天不遂人愿,wa了n次无奈又求助了网络,看到另一种简单的思想,既是找出重复最多的,既是所求。又一次被打败。上边代码中由于对门所在的走廊是一样的 所以可以只算一个也可以都算,都算时若开始为偶数,结束时为奇数则会使两端少算因此加了判断给予补偿。贪心的算法好像是真的不好写,在网上找到的这个是比较常用的,至少我没找到清晰看懂的 用贪心做的,会继续努力,争取早点用贪心写出来。

(3)杭电acm 1236

排名

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18434    Accepted Submission(s): 6701

Problem Description

今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑 
每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的 
考生,并将他们的成绩按降序打印。 

 

 

Input

测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N 
< 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一 
名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号 
(题目号由1M)。 
当读入的考生人数为0时,输入结束,该场考试不予处理。 

 

 

Output

对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高 
到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考 
号的升序输出。 

 

 

Sample Input

4 5 25

10 10 12 13 15

CS004 3 5 1 3

CS003 5 2 4 1 3 5

CS002 2 1 2

CS001 3 2 3 5

1 2 40

10 30

CS001 1 2

2 3 20

10 10 10

CS000000000000000001 0

CS000000000000000002 2 1 2

0

 

 

Sample Output

3

CS003 60

CS001 37

CS004 37

0

1

CS000000000000000002 20

 

Hint

 

Huge input, scanf is recommended.

 

 

 

Source

浙大计算机研究生复试上机考试-2005年 

 

题目大意:

   此题是说要给同学们排名。

题目分析:

   容易看出,这是排序问题,乍一看结构体排序输出,很好理解,实际上用结构体会有麻烦,那就分开存放吧。

代码:

#include<stdio.h>

#include<string.h>

 

char s[1100][25];//存放考生号的

int r[1100];//存放各考生总成绩

int main()

{

     int n,m,g,i,j,k,t,b[15],p,q,v;

     char c[25];//

     while(scanf("%d",&n)!=EOF && n!=0)//考生人数

     {   

      v=0;

      memset(r,0,sizeof(r));

      scanf("%d%d",&m,&g);//考题数,分数线

      for(i=1;i<=m;i++) scanf("%d",&b[i]);//输入各题分值

      for(i=1;i<=n;i++)

      {

            scanf("%s%d",s[i],&p);//输入各考生考号,解题数

           for(j=1;j<=p;j++)

           {

                scanf("%d",&q);//对应题号输入

                r[i]+=b[q];//将成绩存入对应考生(i即是成绩下标也是第几位考生的下标)

           }

           if(r[i]>=g) v++;//记录过分数线人数

      }

     for(i=1;i<n;i++)

      {   

           k=i;

           for(j=i+1;j<=n;j++)

           {

            if(r[j]>r[k]) k=j;//排序,将成绩高的放前面

            else if(r[j]==r[k])

            {

             if(strcmp(s[j],s[k])<0)//若成绩相同按考生号排序

             {

               k=j;//通过下标换进行值的转换,可以保证换了值同时也保证不会打乱成绩与考生对应关系。

             }

   

            }

           }

            t=r[k];

            r[k]=r[i];

            r[i]=t;

            strcpy(c,s[k]);

            strcpy(s[k],s[i]);

            strcpy(s[i],c);//将考生,成绩,进行换位(只是下标其实已经悄无声息换了值)

      }

          printf("%d\n",v);

          if(v>0)

          {

             for(i=1;i<=v;i++) printf("%s %d\n",s[i],r[i]);//输出结果

          }

    }

    return 0;

}

解题分析:

   此题中,这个程序并未用结构体,其实刚开始用的是结构体,但写到中间牵扯到排序时就有点麻烦了,要保证值交换同时,还要考虑对应关系不能乱,真是个棘手的问题,不是不能实现而是真的好麻烦,各种莫名其妙错误,后来还是上网查了啊!哎!没办法,用网络上的思想方法,虽然看起来好像麻烦,但事实上确实简单了许多,所以有时候看起来简单并不一定简单,要思路开阔些,刚开始网络确实很有用啊!错误代码就不再给出,太占篇幅,就是用结构体给出,排序时为了兼顾到对应关系,又加了同时另一变量的值交换,不再赘述。

(4)杭电acm 1863

畅通工程

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 21841    Accepted Submission(s): 9456

Problem Description

省政府畅通工程的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。

 

 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1M编号。当N0时,全部输入结束,相应的结果不要输出。

 

 

Output

对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”

 

 

Sample Input

3 3

1 2 1

1 3 2

2 3 4

1 3

2 3 2

0 100

 

 

Sample Output

3

?

 

 

Source

浙大计算机研究生复试上机考试-2007年 

 

题目大意:

就是要建道路,给出道路,成本计算最少花费。

题目分析:

    是要最少花费,很容易想到用最小生成树,并查集。

代码:

#include <stdio.h>

#include <stdlib.h>

int per[110];

 

struct F

{

    int first;

    int end;

    int pre;

}lu[110];//结构体存放起始终止成本

int cmp(const void *a,const void *b)

{

    struct F *c=(F *)a;

    struct F *d=(F *)b;

    return (c->pre - d->pre);

}

void get()

{

    int i;

    for(i=0;i<110;i++)

       per[i]=i;

}//初始为节点标号

int find(int x)//找根节点

{

    return per[x]==x?x:per[x]=find(per[x]);  

}

int join(int x,int y)//合并两树

{

    int fx=find(x);

    int fy=find(y);

    if(fx!=fy)

       {

           per[fx]=fy;

           return 1;

       }

     return 0;  

}

 

 

int main()

{

    int m,n,i,j;

    while(scanf("%d%d",&n,&m)!=EOF&&n)//路数量,村庄数

    {

        int sum=0,p=0;

        for(i=0;i<n;i++)

        {

            scanf("%d%d%d",&lu[i].first,&lu[i].end,&lu[i].pre);//输入起始终止及成本

        }

        qsort(lu,n,sizeof(lu[0]),cmp);//按成本排序

        get();

        for(i=0;i<n;i++)

        {

            if(join(lu[i].first,lu[i].end))

               sum+=lu[i].pre;

//               printf("~~%d %d\n",per[lu[i].first],per[lu[i].end]);

        }//将两村庄连到一起

//        for(i=0;i<n;i++)

//        {

//            printf("##%d %d\n",per[lu[i].first],per[lu[i].end]);

//        }

        for(i=1;i<=m;i++)

        {

            if(per[i]==i)

            p++;

        }//判断有多少棵树,是否满足题意可以将所有村庄连在一起

        if(p!=1)

        printf("?\n");

        else

        printf("%d\n",sum);//输出对应结果

    }

    return 0;

}

解题分析:

     解题时思路没出问题,就是一些细节总是忽略,调试很久,我认为我这个程序有一个亮点,就是找根节点时只用一句使用?判断看起来很简洁,当然不是我原创,是在书上看来的,感觉很好就借用了,以后可就是我的了。总的说这是我写的之几道题中最值得显摆的,虽然并不好,然而,这是我没有借用别人思想写的,还是很开心呢!

(5)杭电acm 2041

超级楼梯

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 38397    Accepted Submission(s): 19756

Problem Description

有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?

 

 

Input

输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M1<=M<=40,表示楼梯的级数。

 

 

Output

对于每个测试实例,请输出不同走法的数量

 

 

Sample Input

2

2

3

 

 

Sample Output

1

2

 

 

Author

lcy

 

 

Source

2005实验班短学期考试 

 

 

Recommend

lcy

题目大意:

   此题是说有一段楼梯,刚开始站在第一级上,要走上去而且一次可以走一级或两级,问有几种走法。

题目分析:

   看起来,这是一个分析问题,而其则是一个典型的递归问题

代码:

#include <stdio.h>

int m[50];

int i;

 

int find(int x)

{

    m[0]=0;m[1]=1;

    for(i=2;i<=x;i++)

    {

        m[i] = m[i-1]+m[i-2];//递归表达式

    }

    return m[x];

}

int main()

{

    int n,ml,j;

    

    while(scanf("%d",&n)!=EOF)

    {

        for(j=0;j<n;j++)

        {

            scanf("%d",&ml);

            printf("%d\n",find(ml));

        } 

    }

}

解题分析:

   此题刚看到没想到是递归,找规律找了好久没找到,在一次次失败后,问了小伙伴,小伙伴说是递归啊!!简单给我说了后,我经过思考终于明白了,其实就是简单想一下就可以。

当你要上第n级台阶时,有两种方案,第一种就是从n-1级上一级,第二种是从n-2级上2级,所以第n级的方案就是第n-1级的种类加上n-2级的种类所以递归式就是a[n] = a[n-1] + a[n-2];因为题意说了刚开始在第一级上所以,这也就是fibonacci数列了,所以就有了上边程序,经过与朋友交流我终于弄懂了一道题甚是高兴啊!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值