2012金华现场赛四个水题题解(积分赛第四场)

              wust summer contest 4 总结:这次的积分赛又跪了,主要是出题的速度比较慢,思维也没有打开。吉吉发现I是水题,两分半的时候1Y,排名第一。当时我在看J,感觉能把它写出来,当时主要怕一种情况就是clothes 1 pants 1这样的出现两次,当时采取的策略是三个visi数组保存。(当时思维有点混乱),后来又看榜,8086又把J题A了。然后就和吉吉讲了下思路,后来博博也看了这个题,简单的容斥原理。自己当时的思维太固化了,吉吉开始写这个题,然后我就在看K题,J题55分钟1Y。K题模拟的过程也碰见了一些问题,比如撞墙W,N的时候,判断位置,开始写错了。博博写的暴力A超时,吉吉的A也WA了。当时A和K都有人过了,我继续看我的K,吉吉跟博博在看A。到后来才发现竟然是一个条件错误if a rabbit is just about to turn left when two rabbit meet, he will forget to turn this time.就是说如果两个碰到一起了之后,只需要改变成对方的方向即可,不需要再继续向左转。然而自己看的This direction changing is before the judging of whether they should turn around.所以就直接把后面的方向判断忽略了。不仔细!4小时1Y!!TAT。到最后就死奔着A题贪心做,但是吉吉的各种排序WA掉了。到最后也没有灵光一闪想到用b/a排序,没有从两个分析下手。


I - Draw Something
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Wangpeng is good at drawing. Now he wants to say numbers like “521” to his girlfriend through the game draw something.
Wangpeng can’t write the digit directly. So he comes up a way that drawing several squares and the total area of squares is the number he wants to say.
Input all the square Wangpeng draws, what’s the number in the picture?
 

Input

There are multiple test cases.
For each case, the first line contains one integer N(1≤N≤100) indicating the number of squares.
Second line contains N integers ai(1≤ai≤100)represent the side length of each square. No squares will overlap.
Input ends with N = 0.
 

Output

For each case, output the total area in one line.
 

Sample Input

       
       
4 1 2 3 4 3 3 3 3 0
 

Sample Output

       
       
30 27

题目地址:Draw Something

题目意思就不说了。

AC代码:

#include<iostream>
using namespace std;

int main()
{
   int a,b,s;
   while(scanf("%d",&a)&&a)
   {
       s=0;
       for(int i=0;i<a;i++)
       {
         scanf("%d",&b);
         s+=b*b;
       }

       cout<<s<<endl;
   }
   return 0;
}

J - Dressing
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Wangpeng has N clothes, M pants and K shoes so theoretically he can have N×M×K different combinations of dressing.
One day he wears his pants Nike, shoes Adiwang to go to school happily. When he opens the door, his mom asks him to come back and switch the dressing. Mom thinks that pants-shoes pair is disharmonious because Adiwang is much better than Nike. After being asked to switch again and again Wangpeng figure out all the pairs mom thinks disharmonious. They can be only clothes-pants pairs or pants-shoes pairs.
Please calculate the number of different combinations of dressing under mom’s restriction.
 

Input

There are multiple test cases.
For each case, the first line contains 3 integers N,M,K(1≤N,M,K≤1000) indicating the number of clothes, pants and shoes.
Second line contains only one integer P(0≤P≤2000000) indicating the number of pairs which mom thinks disharmonious.
Next P lines each line will be one of the two forms“clothes x pants y” or “pants y shoes z”.
The first form indicates pair of x-th clothes and y-th pants is disharmonious(1≤x≤N,1 ≤y≤M), and second form indicates pair of y-th pants and z-th shoes is disharmonious(1≤y≤M,1≤z≤K).
Input ends with “0 0 0”.
It is guaranteed that all the pairs are different.
 

Output

For each case, output the answer in one line.
 

Sample Input

       
       
2 2 2 0 2 2 2 1 clothes 1 pants 1clothes 1 pants 1 2 2 2 2 clothes 1 pants 1 pants 1 shoes 1 0 0 0
 

Sample Output

       
       
8 6 5
 

题目大意:给你衣服n,裤子m,鞋子k,从1到他们编号。然后开始搭配,但是clothes 1 pants 1就说明这样的衣服1和裤子1不能搭配。

解题思路:由于输入不能搭配的只有两种情况clothes a pants b和pants b shoes c的情况,在自己草稿纸上写一下a与b:1-2,3-2,4-2.b与c:2-1,2-2.会想到用容斥原理解决,公式为res=res-p1[i]*k-p2[i]*n+p1[i]*p2[i].res开始为n*m*k.p1[i]与p2[i]的含义见代码注释。


题目地址:Dressing


AC代码:

#include<iostream>
#include<cstring>
#include<cmath>
#include<string>
#include<cstdio>
using namespace std;
char a1[20],a2[20];
int p1[1005],p2[1005],t1,t2,i;  //p1[i]记录标号为i的裤子不能搭配的上衣数量
                        //p2[i]记录标号为i的裤子不能搭配的鞋子数量
int main()
{
     int n,m,k,p,res;
     while(scanf("%d%d%d",&n,&m,&k))
     {
          if(n==0&&m==0&&k==0)
               break;
          res=n*m*k;
          memset(p1,0,sizeof(p1));
          memset(p2,0,sizeof(p2));
          scanf("%d",&p);
          while(p--)
          {
               scanf("%s%d%s%d",a1,&t1,a2,&t2);
               if(strcmp(a1,"clothes")==0)
                    p1[t2]++;
                 else
                    p2[t1]++;
          }
          for(i=1;i<=m;i++)
               res=res-p1[i]*k-p2[i]*n+p1[i]*p2[i];
               
          printf("%d\n",res);
     }
     return 0;
}

K - Running Rabbits
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Rabbit Tom and rabbit Jerry are running in a field. The field is an N×N grid. Tom starts from the up-left cell and Jerry starts from the down-right cell. The coordinate of the up-left cell is (1,1) and the coordinate of the down-right cell is (N,N)。A 4×4 field and some coordinates of its cells are shown below:

The rabbits can run in four directions (north, south, west and east) and they run at certain speed measured by cells per hour. The rabbits can't get outside of the field. If a rabbit can't run ahead any more, it will turn around and keep running. For example, in a 5×5 grid, if a rabbit is heading west with a speed of 3 cells per hour, and it is in the (3, 2) cell now, then one hour later it will get to cell (3,3) and keep heading east. For example again, if a rabbit is in the (1,3) cell and it is heading north by speed 2,then a hour latter it will get to (3,3). The rabbits start running at 0 o'clock. If two rabbits meet in the same cell at k o'clock sharp( k can be any positive integer ), Tom will change his direction into Jerry's direction, and Jerry also will change his direction into Tom's original direction. This direction changing is before the judging of whether they should turn around.
The rabbits will turn left every certain hours. For example, if Tom turns left every 2 hours, then he will turn left at 2 o'clock , 4 o'clock, 6 o'clock..etc. But if a rabbit is just about to turn left when two rabbit meet, he will forget to turn this time. Given the initial speed and directions of the two rabbits, you should figure out where are they after some time.
 

Input

There are several test cases.
For each test case:
The first line is an integer N, meaning that the field is an N×N grid( 2≤N≤20).
The second line describes the situation of Tom. It is in format "c s t"。c is a letter indicating the initial running direction of Tom, and it can be 'W','E','N' or 'S' standing for west, east, north or south. s is Tom's speed( 1≤s<N). t means that Tom should turn left every t hours( 1≤ t ≤1000).
The third line is about Jerry and it's in the same format as the second line.
The last line is an integer K meaning that you should calculate the position of Tom and Jerry at K o'clock( 1 ≤ K ≤ 200).
The input ends with N = 0.
 

Output

For each test case, print Tom's position at K o'clock in a line, and then print Jerry's position in another line. The position is described by cell coordinate.
 

Sample Input

     
     
4 E 1 1 W 1 1 2 4 E 1 1 W 2 1 5 4 E 2 2 W 3 1 5 0
 

Sample Output

     
     
2 2 3 3 2 1 2 4 3 1 4 1
 

题目大意:n*n的方格,两个兔子,一个在左上角,一个右下角,然后开始跑。两个兔子有各自的速度,然后有方向,还有每一定的时间,兔子会向左转改变自己的方向。两个兔子相撞,方向互换,不需要向左转。输出某一时刻他们两个的位置。

解题思路:模拟题,具体思路见代码,主要就是要注意细节。

题目地址:Running Rabbits


AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <stack>
#include <vector>
#include <map>
#include <queue>
using namespace std;

int main()
{
    int n,a,b,c,d,v1,v2,t1,t2,p1,p2,t,i;
    //(a,b),(c,d)是兔子的坐标,v是速度,t是向左转的时刻,p是兔子的方向,t是总时间
    while(scanf("%d",&n)&&n)
    {
        a=1,b=1,c=n,d=n;
        char x;
        cin>>x;
        if(x=='E')
            p1=3;
         else if(x=='N')
            p1=2;
          else if(x=='W')
            p1=1;
            else
              p1=0;
        scanf("%d%d",&v1,&t1);
        cin>>x;
        if(x=='E')
            p2=3;
         else if(x=='N')
            p2=2;
          else if(x=='W')
            p2=1;
            else
              p2=0;
        scanf("%d%d",&v2,&t2);
        scanf("%d",&t);
        //如果向东撞墙的话,就是a和c不变b=2*n-(b+v1); 开始位置也弄颠倒了
        //如果向西撞墙的话,就是a和c不变b=2-(b-v1);  这里当时也写错了
        //同理向北向南
        for(i=1;i<=t;i++)
        {
            //cout<<"****"<<p1<<" "<<p2<<endl;
            if(p1==3)   //E
            {
                b+=v1;
                if(b>n)
                {
                    p1=1;   //如果超出格子,改变方向
                    b=2*n-b;
                }
            }
             else if(p1==2)  //S
             {
                 a-=v1;
                 if(a<1)
                 {
                     p1=0;
                     a=2-a;
                 }
             }
               else if(p1==1)  //W
               {
                   b-=v1;
                   if(b<1)
                   {
                       p1=3;
                       b=2-b;
                   }
               }
                 else if(p1==0)  //N
                 {
                     a+=v1;
                     if(a>n)
                     {
                       p1=2;
                       a=2*n-a;
                    }
                 }
            if(p2==3)
            {
                d+=v2;
                if(d>n)
                {
                    p2=1;
                    d=2*n-d;
                }
            }
             else if(p2==2)
             {
                 c-=v2;
                 if(c<1)
                 {
                     p2=0;
                     c=2-c;
                 }
             }
               else if(p2==1)
               {
                   d-=v2;
                   if(d<1)
                   {
                       p2=3;
                       d=2-d;
                   }
               }
                 else if(p2==0)
                 {
                     c+=v2;
                     if(c>n)
                     {
                       p2=2;
                       c=2*n-c;
                    }
                 }

            if(a==c&&b==d)   //判断两只兔子碰撞
            {
                int tmp=p1;
                p1=p2;
                p2=tmp;
            }
            else
            {
              if(i%t1==0)
                p1=(p1-1+4)%4;   //向左转
              if(i%t2==0)
                p2=(p2-1+4)%4;
            }
        }
        printf("%d %d\n%d %d\n",a,b,c,d);
    }
    return 0;
}

A - Physical Examination
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

WANGPENG is a freshman. He is requested to have a physical examination when entering the university.
Now WANGPENG arrives at the hospital. Er….. There are so many students, and the number is increasing!
There are many examination subjects to do, and there is a queue for every subject. The queues are getting longer as time goes by. Choosing the queue to stand is always a problem. Please help WANGPENG to determine an exam sequence, so that he can finish all the physical examination subjects as early as possible.
 

Input

There are several test cases. Each test case starts with a positive integer n in a line, meaning the number of subjects(queues).
Then n lines follow. The i-th line has a pair of integers (ai, bi) to describe the i-th queue:
1. If WANGPENG follows this queue at time 0, WANGPENG has to wait for ai seconds to finish this subject.
2. As the queue is getting longer, the waiting time will increase bi seconds every second while WANGPENG is not in the queue.
The input ends with n = 0.
For all test cases, 0<n≤100000, 0≤a i,b i<2 31.
 

Output

For each test case, output one line with an integer: the earliest time (counted by seconds) that WANGPENG can finish all exam subjects. Since WANGPENG is always confused by years, just print the seconds mod 365×24×60×60.
 

Sample Input

       
       
5 1 2 2 3 3 4 4 5 5 6 0
 

Sample Output

       
       
1419

Hint

In the Sample Input, WANGPENG just follow the given order. He spends 1 second in the first queue, 5 seconds in the 2th queue, 27 seconds in the 3th queue, 
169 seconds in the 4th queue, and 1217 seconds in the 5th queue. So the total time is 1419s. WANGPENG has computed all possible orders in his 
120-core-parallel head, and decided that this is the optimal choice.
 
 

题目大意:给你n个队,每一个队有自己排队所需的时间,每一秒再排此队会增加的时间。


解题思路:博博的思路是每次看一下,排哪个队会让其他的队增加的时间最少,这样会超时。思路需要简化到先比较两个,例如i ai bi j aj bj先选i队还是j队如何抉择。如果先选i的话用时ai+aj+ai*bj. 而先选j的话用时aj+ai+aj*bi 要先选i则只需要判断ai/bi<aj/bj.两个判断好了,剩下的时间肯定是最短的了。

题目地址:Physical Examination

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int MO = 365*24*60*60;
struct node
{
     int a;
     int b;
}p[100005];

int cmp(node t1,node t2)
{
     if(double(t1.a)/double(t1.b)<double(t2.a)/double(t2.b))
          return 1;
       else
          return 0;
}

int main()
{
   int n,i;
   __int64 res,t;
   while(scanf("%d",&n)&&n)
   {
        for(i=0;i<n;i++)
           scanf("%d%d",&p[i].a,&p[i].b);
        sort(p,p+n,cmp);
        res=0;   
        for(i=0;i<n;i++)
            res=(res+res*p[i].b+p[i].a)%MO;
        printf("%I64d\n",res);
   }
   return 0;
}

革命尚未成功,同志仍需努力!!@BME

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值