南阳理工 5月8日 月赛 总结

我是从三点多才知道有比赛的,所以只剩下不到两个多小时,中间肚子疼,又上厕所一次,真是的。。参加吧,捡到哪到是哪到~

不吉利的数字

时间限制:1000 ms  |  内存限制:65535 KB
 
描述

 一些普通的数字在很多人眼里是不吉利。如数字4,谐音“死”,所以很多地方都没有带4的数字:比如新校区澡堂衣柜编号及没有4;再如数字13,在西方人眼中代表着坏运气,也是不吉利的数字,13不出远门,楼层不设第13层等等。

假如某些人认为0是不吉利的数字,并且在他们以后的生活中,记录数据都在不在使用含有0的自然数。

他们记录数的序列是1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,21,22.......n,由于不使用数字0,他们记录的数和我们实际使用的自然数有一定的差别,如他们的11,实际就是第10个数,21就是第19个数,以此类推。。。   

现在给你一个数n,请判断在不不含0的序列中的,如果在,求n是第几个数,不在,输出Unlucky。

Hint:  105,10523等等,都是含有0的

 
输入
有多组测试数据<5000
每组数据占一行,每行有一个数n(0<=n<=1000000)。
以EOF结尾
输出
每组输出占一行,如果n在不含0的序列中,输出是第几个。如果不在不含0的序列中,输出Unlucky;
样例输入
11
9
21
10
样例输出
10
9
19
Unlucky

【我的代码】这道题非常简单,5分钟AC:
 1 import java.util.Scanner;
 2 
 3 
 4 public class Main3 {
 5     static int t=1000001;
 6     static int a[]=new int[t];
 7   public static void main(String args[]){
 8   Scanner cin=new Scanner(System.in);
 9     String str="";  
10     int sum=1;
11     
12  
13   for(int i=1;i<t;i++){
14         str=i+"";
15         boolean f=false;
16         for(int j=0;j<str.length();j++){
17             if(str.charAt(j)=='0') {
18              f=true;
19              break;
20             } 
21         }
22         if(!f)
23         a[i]=sum++;
24     }
25       while(cin.hasNext()){
26           int num=cin.nextInt();
27           if(a[num]==0)
28           System.out.println("Unlucky");
29           else
30               System.out.println(a[num]);
31       }
32   }
33 }

数棋盘

时间限制:1000 ms  |  内存限制:65535 KB
 
描述
一个有N×N个格子的正方形棋盘,每个格子可以用C种不同颜色来染色,一共可以得到多少种不同的棋盘。如果一个棋盘,经过任意旋转,反射后变成另一个棋盘,这两个棋盘就是属于同一种棋盘。
比如当N=C=2的时候,有下面六种不同的棋盘:

现在告诉你N和C,请你算算,到底有多少种不同的棋盘.

 输入
本题目包含多组测试,请处理到文件结束。
每组测试数据包含两个正整数N和C(0<N,C,<31),分别表示棋盘的大小是N×N,用C种颜色来进行染色。
输出
对于每组测试,在一行里输出答案。
样例输入
2 2
3 1
样例输出
6
1

以前看过相关的解题报告,好在我记住了,不过中间还是忘了一些,又回忆了一下,证明了一下:
【我的代码】
 1 import java.util.*;
 2 import java.math.*;
 3 public class Main {
 4 
 5  
 6     public static void main(String[] args) { 
 7         Scanner cin= new Scanner(System.in);
 8         while(cin.hasNextInt())
 9         {
10     
11             BigInteger sum=BigInteger.ZERO;
12             int n=cin.nextInt();
13             int m=cin.nextInt();
14             BigInteger M=BigInteger.valueOf(m);
15             sum=sum.add(M.pow(n*n));
16             sum=sum.add(M.pow((n*n+3)/4));
17             sum=sum.add(M.pow((n*n+1)/2));
18             sum=sum.add(M.pow((n*n+3)/4));
19             if(n%2 == 0)
20             {
21                 sum=sum.add(M.pow(n*n/2).add(M.pow(n*(n-1)/2+n)).multiply(BigInteger.valueOf(2)));
22             }
23             else
24                 sum=sum.add(M.pow(n*(n-1)/2+n).multiply(BigInteger.valueOf(4)));
25             System.out.println(sum.divide(BigInteger.valueOf(8)));
26         }
27 
28     }
29 }

太空飞行计划

时间限制:1000 ms  |  内存限制:65535 KB
 
描述
       W 教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={I1,I2,…In}。实验Ej需要用到的仪器是I的子集Rj 。配置仪器Ik的费用为ck美元。实验Ej的赞助商已同意为该实验结果支付pj美元。W教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。
    对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。
 
 
输入
多组测试数据(不超过500组)
每组数据第1行有2 个正整数m和n(m,n <= 100)。m是实验数,n是仪器数。接下来的m 行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用f(f < 10000);接着是该实验需要用到的仪器的个数t,接着是t个仪器的编号。最后一行的n个数是配置每个仪器的费用pi(pi <=100)。
输出
每组数据输出占一行,输出最大的净收益(如果无法收益,输出0)。
样例输入
2 3
10 2 1 2
25 2 2 3
5 6 7
样例输出
17

【我的代码】第一次想的太简单:c-wrong:
 1 import java.util.*;
 2 public class Mainflyplan {
 3   public static void main(String args[]){
 4       Scanner cin=new Scanner(System.in);
 5       int m=cin.nextInt(); //实验数
 6       int n=cin.nextInt(); //仪器数
 7 
 8       Sy a[]=new Sy[m];
 9       for(int i=0;i<m;i++){
10           Sy sy=new Sy();
11           sy.fi=cin.nextInt();
12           sy.num=cin.nextInt();
13           sy.init();
14           for(int j=0;j<sy.num;j++)
15               sy.a[j]=cin.nextInt();
16           
17           a[i]=sy;
18       }
19       int fi[]=new int[n+1];
20       for(int i=1;i<n+1;i++)  //输入仪器费用
21           fi[i]=cin.nextInt();
22       
23       int sum=0;   //总盈利
24       int old=-1;  //判断每次循环是否最大值有变化,无变化则挑出
25       
26       int oldenum=-1;
27       int equnum=0;
28       boolean euse[]=new boolean[n+1]; //n个仪器是否被选择
29        int tmpe=0;
30        
31    while(oldenum!=equnum|old!=sum){  //条件应当是 仪器数没有改变,最大值也没有改变的时候
32        
33        
34        old=sum;       
35        
36        
37 //       tmpe=0;
38 //       for(int i=1;i<=n;i++)
39 //          if(euse[i]) tmpe++;
40        
41        oldenum=equnum;
42       for(int i=0;i<m;i++){  //对实验个数进行遍历
43           if(!a[i].flag){  //没有被收录
44                int ecost=0;//当前循环加入该实验所需要配置仪器的总费用
45               for(int j=0;j<a[i].num;j++){
46                   int now=a[i].a[j];
47                   if(euse[now])
48                       ecost+=0;  //已经被收录则无需费用
49                   else{ 
50                       ecost+=fi[now];
51                   }
52               }
53               
54               a[i].benfit=a[i].fi-ecost;  //当前循环加入该实验的收益
55               if(a[i].benfit>=0){ //如果收益大于0  等于0也应当收录,这样为后来有更多的仪器有保证
56                   sum+=a[i].benfit;
57                   a[i].flag=true;
58         
59                   for(int k=0;k<a[i].num;k++){
60                       int now=a[i].a[k];
61                       euse[now]=true;
62                   }
63                   
64                    tmpe=0;   //更新仪器数
65                    for(int p=1;p<=n;p++)
66                       if(euse[p]) tmpe++;
67                    equnum=tmpe;   //更新仪器数
68               }
69           }
70       }
71    }
72    System.out.println(sum);
73       
74   }
75   
76   
77 }
78 class Sy
79 {
80     boolean flag=false; //是否被收录
81     int fi=0;
82     int num=0;
83     int a[];
84     int benfit=0;  
85     public void init(){
86         a=new int[num];
87     }
88 }

【我的代码】 修改后:

 1 import java.util.*;
 2 public class Main {
 3   public static void main(String args[]){
 4       Scanner cin=new Scanner(System.in);
 5       int m=cin.nextInt(); //实验数
 6       int n=cin.nextInt(); //仪器数
 7 
 8       Sy a[]=new Sy[m];
 9       for(int i=0;i<m;i++){
10           Sy sy=new Sy();
11           sy.fi=cin.nextInt();
12           sy.num=cin.nextInt();
13           sy.init();
14           for(int j=0;j<sy.num;j++)
15               sy.a[j]=cin.nextInt();
16           
17           a[i]=sy;
18       }
19       int fi[]=new int[n+1];
20       for(int i=1;i<n+1;i++)  //输入仪器费用
21           fi[i]=cin.nextInt();
22       
23       int sum=0;   //总盈利
24  
25       boolean euse[]=new boolean[n+1]; //n个仪器是否被选择
26  
27  
28  
29       for(int i=0;i<m;i++){  //对实验个数进行遍历
30           int s=0;
31           for(int j=0;j<m;j++){
32               if(a[j].flag) s++;
33           }
34           if(s==m) break;
35                        
36                //找到最大应该加入的方案
37          
38                int max=-1,maxp=0;
39                
40                for(int k=0;k<m;k++){
41                    if(!a[k].flag){
42                    int ecost=0;//当前循环加入该实验所需要配置仪器的总费用
43               for(int j=0;j<a[k].num;j++){
44                   int now=a[k].a[j];
45                   if(euse[now])
46                       ecost+=0;  //已经被收录则无需费用
47                   else{ 
48                       ecost+=fi[now];
49                   }
50               }
51               
52               a[k].benfit=a[k].fi-ecost;  //当前循环加入该实验的收益
53               
54               if(a[k].num==0) {max=a[k].benfit;maxp=k; break;}
55               else
56               if(a[k].benfit==0){max=a[k].benfit;maxp=k;}
57               else
58               if(a[maxp].benfit!=0&&max<a[k].benfit) {max=a[k].benfit;maxp=k;}
59                }
60                }
61                
62              if(!a[maxp].flag){
63                   sum+=a[maxp].benfit;
64                   a[maxp].flag=true;
65         
66                   for(int k=0;k<a[maxp].num;k++){
67                       int now=a[maxp].a[k];
68                       euse[now]=true;
69                   }
70                   
71              }
72      
73      
74  
75  
76           }
77  
78  
79  
80    System.out.println(sum);
81       
82   }
83   
84   
85 }
86 class Sy
87 {
88     boolean flag=false; //是否被收录
89     int fi=0;
90     int num=0;
91     int a[];
92     int benfit=0;  
93     public void init(){
94         a=new int[num];
95     }
96 }

 南开AC:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #define maxn 500
  7 #define maxm 1000
  8 #define inf 1000000000
  9 using namespace std;
 10  
 11 int gap[maxn],dis[maxn],pre[maxn],cur[maxn];
 12 int NV,n,m;
 13  
 14 struct Edge {
 15     int v,next,val;
 16     Edge(){}
 17     Edge( int V , int NEXT , int VAL ):v(V),next(NEXT),val(VAL){}
 18 }edge[maxm];
 19 int cnt_edge,head[maxn];
 20 bool vis[maxn];
 21  
 22 void Insert_Edge( int u , int v , int flow = 0 ) {
 23     //printf("%d->%d,%d\n",u,v,flow);
 24     edge[cnt_edge] = Edge(v,head[u],flow);
 25     head[u] = cnt_edge++;
 26     edge[cnt_edge] = Edge(u,head[v],0);
 27     head[v] = cnt_edge++;
 28 }
 29  
 30 void Init() {
 31     cnt_edge = 0;
 32     memset(head,-1,sizeof(int)*NV);
 33     memset(vis,false,sizeof(vis));
 34 }
 35  
 36 int Sap( int st , int en ) {
 37     for( int i = 0 ; i < NV ; i++ ) {
 38         dis[i] = gap[i] = 0;
 39         cur[i] = head[i];
 40     }
 41     int u = pre[st] = st, maxflow = 0,aug = inf;
 42     gap[0] = NV;
 43     while( dis[st] < NV ) {
 44 loop:    for( int &i = cur[u] ; i != -1 ; i = edge[i].next ) {
 45             int v = edge[i].v;
 46             if( edge[i].val && dis[u] == dis[v] + 1 ) {
 47                 aug = aug<edge[i].val?aug :edge[i].val;
 48                 pre[v] = u;
 49                 u = v;
 50                 if( v == en ) {
 51                     maxflow += aug;
 52                     for( u = pre[u] ; v != st ; v = u , u = pre[u] ) {
 53                         edge[ cur[u] ].val -= aug;
 54                         edge[ cur[u]^1 ].val += aug;
 55                     }
 56                     aug = inf;
 57                 }
 58                 goto loop;
 59             }
 60         }
 61         int mindis = NV;
 62         for( int i = head[u] ; i != -1 ; i = edge[i].next ) {
 63             int v = edge[i].v;
 64             if( edge[i].val && mindis > dis[v] ) {
 65                 cur[u] = i;
 66                 mindis = dis[v];
 67             }
 68         }
 69         if( --gap[dis[u]] == 0 ) break;
 70         gap[ dis[u] = mindis + 1 ]++;
 71         u = pre[u];
 72     }
 73     return maxflow;
 74 }
 75  
 76 void Dfs( int u ) {
 77     vis[u] = true;
 78     //printf("u = %d\n",u);
 79     int v;
 80     for( int i = head[u] ; i != -1  ; i = edge[i].next ) {
 81         //printf("i = %d\n",i);
 82         v = edge[i].v;
 83         //printf("v=%d\n",v);
 84         if( !vis[v] && edge[i].val ) Dfs(v);
 85     }
 86 }
 87  
 88 int main() {
 89     while( scanf("%d%d",&m,&n) != EOF ) {
 90         NV = n + m + 2;
 91         Init();
 92         int st = 0;
 93         int en = NV - 1;
 94         int w,num,tp,sum = 0;
 95         char cc;
 96         for( int i = 1 ; i <= m ; i++ ) {
 97             scanf("%d",&w);
 98             sum += w;
 99             Insert_Edge(st,i,w);
100             while(scanf("%d%c",&tp,&cc)) {
101                 //printf("~%c~",cc);
102                 Insert_Edge(i,tp+m,inf);
103                 if( cc == '\n' ) break;
104             }
105         }
106         for( int i = 1 ; i <= n ; i++ ) {
107             scanf("%d",&tp);
108             Insert_Edge(i+m,en,tp);
109         }
110         //for( int i = head[0] ; i != -1 ; i = edge[i].next ) {
111         //    printf("i = %d\n",i);
112         //    printf("v=%d\n",edge[i].v);
113         //}
114         int res = sum - Sap(st,en);
115         Dfs(st);
116         int id;
117         for( id = 1 ; id <= m ; id++ ) {
118             if( vis[id] ) {
119                 printf("%d",id);
120                 break;
121             }
122         }
123         for( id++ ; id <= m ; id++ ) {
124             if( vis[id] ) printf(" %d",id);
125         }
126         puts("");
127         for( id = 1 ; id <= n ; id++ ) {
128             if( vis[id+m] ) {
129                 printf("%d",id);
130                 break;
131             }
132         }
133         for( id++ ; id <= n ; id++ ) {
134             if( vis[id+m] ) printf(" %d",id);
135         }
136         puts("");
137  
138         printf("%d\n",res);
139     }
140     return 0;
141 }

南阳的系统有问题,第三题所有的都没有结果。但是在南开就AC了。。

后面三道题在做其中一道时候,已经没有时间了,都读完了题目,分析了一下,郁闷。。才进入状态就。。评测系统就关闭了。。。

flip这道题是原题。。

hotel这道题用数组应该比较好过的。

比赛结束复制了一下全部比赛提交AC结果:

Problem A   不吉利的数字 35 % (22/62)
Problem B   数棋盘 44 % (4/9)
  Problem C   太空飞行计划 0 % (0/28)
  Problem D   flip 76 % (16/21)
  Problem E   move 21 % (3/14)
  Problem F   K steps 0 % (0/2)
  Problem G   hotel 0 % (0/0)
感觉这次还是蛮有意思的,可能是热身赛吧,感觉容易题还是蛮容易的。。
 

flip

时间限制:1000 ms  |  内存限制:65535 KB
 
描述
Give you a non-negative integer x and an operation. The only operation you can do is to reverse one bit in binary form of x 
 
once(i.e 1->0, 0->1).
your goal is to turn x into x+1.
Calculate the minimum times of operations you need to do. 
 
输入
The first line of the input is an integer T indicates the test cases.
Then follow T lines. Each line is a non-negative integer x as described above, note that 0<=x<10^9.
输出
Output the minimum times of operations you need to do to reach the goal.
样例输入
3
1
2
3
样例输出
2
1
3

题目翻译:

flip
时间限制:1000 ms | 内存限制:65535 KB
描述

给你一个非负的正整数x和一种操作。你只能做将二进制格式的x的某一位反转这样一个操作。
一次(例如1->0,0->1)
你的目的是 返回令x变成x+1

计算达到目标最小的操作次数。

输入
第一行输入是一个正整数T代表测试的数据组数。
随后的T行,每一行是一个从上描述的非负正整数x,注意0<=x<10^9.

输出
输入达到目标最小的操作次数
样例输入
3
1
2
3
样例输出
2
1
3



【朋友的代码】我们是单独分开做的,我在寝室,他在实验室,他做出来两道,时间和我差不多,他的代码:
 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int t;
 8     cin>>t;
 9     while(t--)
10     {
11         int n,i=0,j=0,a[32],b[32],sum,k=0,g;
12         cin>>n;
13         sum=n+1;
14         while(true)
15         {
16             if(n==1)
17             {
18                a[i]=1;
19                i++;
20                break;
21             }
22             else
23             {
24                 a[i]=n%2;
25                 n=n/2;
26                 i++;
27             }
28         }
29         while(true)
30         {
31             if(sum==1)
32             {
33                b[j]=1;
34                j++;
35                break;
36             }
37             else
38             {
39                 b[j]=sum%2;
40                 sum=sum/2;
41                 j++;
42             }
43         }
44         if(i==j)
45         {
46              for(g=0;g<i;g++)
47              {
48                 if(a[g]!=b[g])
49                 {
50                    k++;
51                 }
52              }  
53         }
54         else
55         {
56            for(g=0;g<i;g++)
57              {
58                 if(a[g]!=b[g])
59                 {
60                    k++;
61                 }
62              }
63              k++;   
64         }
65         cout<<k<<endl;
66     }
67 }

move

时间限制:10000 ms  |  内存限制:65535 KB
 
描述

Do you ever become frustrated with television because you keep seeing the same things, recycled over and over again? Well I personally don't care about television, but I do sometimes feel that way about numbers.

Let's say a pair of distinct positive integers (nm) is recycled if you can obtain m by moving some digits from the back of n to the front without changing their order. For example, (12345, 34512) is a recycled pair since you can obtain 34512 by moving 345 from the end of 12345 to the front. Note that n and m must have the same number of digits in order to be a recycled pair. Neither n nor m can have leading zeros.

Given integers A and B with the same number of digits and no leading zeros, how many distinct recycled pairs (nm) are there with A ≤ n < m ≤ B?

 
输入
The first line of the input gives the number of test cases, T(1 ≤ T ≤ 50.). T test cases follow. Each test case consists of a single line containing the integers A and B.(1 ≤ A ≤ B ≤ 2000000)
输出
For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1), and y is the number of recycled pairs (n, m) with A ≤ n < m ≤ B.
样例输入
4
1 9
10 40
100 500
1111 2222
样例输出
Case #1: 0
Case #2: 3
Case #3: 156
Case #4: 287

题目翻译:

move
时间限制:10000 ms | 内存限制:65535 KB
描述
你曾今是否为电视节目的反复出现总是看到同样的东西而感到沮丧?当然我个人并不关心电视,而是关心与其具有同样性质的数字。

让我们来说一说以相互不同的正整数组成的一对(n,m)“往复数”,如果一对数(n,m),其中你能够通过移动n的后面几位数字到它的前面得到m,则我们称这对数为“往复数”。举例来说,由于可以通过移动12345的345到12的前面来得到34512, (12345, 34512) 就是一对“往复数”。值得注意的是,n和m必须是同样位数的数才可以成为“往复数”。n和m都不能以0开头。

给你一对具有相同位数并且都不以0开头的整数A和B,你能够找到多少个互不相同的“往复数”组合(n,m),且它们都满足A ≤ n < m ≤ B?

输入
第一行是测试数据的组数T。T(1 ≤ T ≤ 50.)
随后T行测试数据,每一行是一组测试数据,包含正整数A和B(1 ≤ A ≤ B ≤ 2000000)

输出
对于每一组测试数据,输出一行包含"Case #x: y",x代表为第几组测试数据(从1开始),y是计算出的满足A ≤ n < m ≤ B的“往复数”对数。 (一个(n,m)算一对)


K steps

时间限制:2000 ms  |  内存限制:65535 KB
 
描述
Here are n beautiful towns and m roads(directional edge). yjx wants to visit these towns for relaxation when he suddenly 
got a question. He wants to know the number of schemes  to walk from town A to town B in exactly k steps.A road can be 
visited more then once. It takes exactly one step to walk from one town to another if they are directly connected by a road.
yjx is very entangled with this matter, please help him.
 
输入
First line is a number T, the number of the cases.
Each case is as follows:
First line includes four number: n, m, k, l which means n(1 <= n <= 100)towns, m(1 <= m<=1000)roads, k(1<=k<=1000)steps,
and l (1<=l<=1000) lines test data.
Then there are m lines, and each line is made up of two number u, v (u != v, 1<= u,v <= n) which means one road from u to v.
Then l lines test data, and each line is made up of two number p, q (so you must help yjx to know the number of the scheme that just walk k steps from town p to town q).
hint: maybe there are more than one road from u to v .
输出
For each test data, output the number of the scheme(the number is big, so you must make the number mod 1991).
样例输入
2
2 2 1 2
1 2
2 1
1 2
2 1
3 2 2 1
1 2
2 3
1 3
样例输出
1
1
1
题目翻译:

K steps
时间限制:2000 ms | 内存限制:65535 KB
描述
这里有n个漂亮的城镇和m条道路(直接相连),yjx想要在这几个城镇之间游玩,但是他突然遇到一个问题。他想知道使用K步从城镇A到城镇B一共有几种走法。一条路能够被走多次,并且从一个城镇到达另一个城镇(如果他们之间是被路直接相连的)只需要一步即到。
yjx对这个问题非常抓狂,所以请求你帮助。

输入
第一行是T,代表测试数据的组数。
每一组测试用例:第一行包括四个数字 n, m, k, l ,它们分别代表n(1 <= n <= 100)城镇,m(1 <= m<=1000)道路, k(1<=k<=1000)步,l (1<=l<=1000) 行测试数据。
随后的m行,每一行是由 u, v (u != v, 1<= u,v <= n) 两个数构成的,代表一条从u到v的路
随后的l行测试数据,每一行由p, q两个数组成,这是yjx想知道从p城镇到q城镇走k步的不同走法数。

提示:从u到v可能有大于1条道路。

输出
对于每组测试数据,输出总的方案数(这个数是非常大的,所以你必须使这个数mod1991再输出)
样例输入
2
2 2 1 2
1 2
2 1
1 2
2 1
3 2 2 1
1 2
2 3
1 3
样例输出
1
1
1

hotel

时间限制:1000 ms  |  内存限制:65535 KB
 
描述

The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).

The cows and other visitors arrive in groups of size Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.

Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms Xi ..Xi +Di-1 (1 ≤ Xi≤ N-Di+1). Some (or all) of those rooms might be empty before the checkout.

Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.

 
输入
* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 and Di (b) Three space-separated integers representing a check-out: 2, Xi, and Di
输出
* Lines 1.....: For each check-in request, output a single line with a single integer r, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 0.
样例输入
10 6
1 3
1 3
1 3
1 3
2 5 5
1 6
样例输出
1
4
7
0
5
题目翻译:

hotel
时间限制:1000 ms | 内存限制:65535 KB
描述
cows一路向北到的加拿大Thunder Bay来丰富自己的文化和享受阳光海岸度假。Bessie曾建是一家旅行社的主管,现在被任命为著名的位于Cumberland 街道的Bullmoose 酒店的总管。这间巨大的酒店拥有N (1 ≤ N ≤ 50,000) 个房间,房间都位于湖的同一侧的(当然这些房间都能够很好的欣赏湖的美景)。

cows和其他的参观者以Di (1 ≤ Di ≤ N)个人这样的群体到达,并且到前台来登记入住,每第i一群人请求Canmuu(酒店员工)分配Di数目的连续的房间给他们这群人入住。如果空房间数允许,Canmuu将分配 r..r+Di-1给这群人,如果没有他们请求的号码的连续的房间,则建议他们选择候选的由酒店分配的号码,Canmuu 总是选择最小的r来分配给客户。

旅游者同样也按照连续的方式进行入住。第i群人登出(住完走人)参数 Xi和Di代表房间Xi ..Xi +Di-1 (1 ≤ Xi≤ N-Di+1)不住了。在他们到台前办理登出之前,这些房间中的一些(或者所有)也许是空的。

你的工作就是帮助Canmuu 处理M (1 ≤ M < 50,000) 的入住/登出请求,酒店初始是空的。

输入
第一行:两个以空格分开的整数:N和M
第二行到第M+1行:第i+1行包含两种可能的请求格式:(a) 两个以空格分开的整数 1 and Di代表入住请求 (b)三个以空格分开的整数代表一个登出请求:2, Xi, and Di

输出
对于每一个入住请求输出一行,这一行包含一个整数r,r代表连续入住房间的第一个房间号。如果请求不能够满足,输出0

样例输入
10 6
1 3
1 3
1 3
1 3
2 5 5
1 6
样例输出
1

 

欢迎转载,转载请注明出处。本文出自:http://www.cnblogs.com/zdcaolei
0
原文地址:https://www.cnblogs.com/zdcaolei/p/2490547.html