首页 > 代码库 > Usaco Open09 Silver

Usaco Open09 Silver

**********************************************************************
                           SILVER PROBLEMS
**********************************************************************
                  Four problems numbered 6 through 9
**********************************************************************

Problem 6: Hide and Seek [Jacob Steinhardt, 2009]

Bessie is playing hide and seek (a game in which a number of players
hide and a single player (the seeker) attempts to find them after
which various penalties and rewards are assessed; much fun usually
ensues).

She is trying to figure out in which of N (2 <= N <= 20,000) barns
conveniently numbered 1..N she should hide. She knows that FJ (the
seeker) starts out in barn 1. All the barns are connected by M (1
<= M <= 50,000) bidirectional paths with endpoints A_i and B_i (1
<= A_i <= N; 1 <= B_i <= N; A_i != B_i); it is possible to reach
any barn from any other through the paths.

Bessie decides that it will be safest to hide in the barn that has
the greatest distance from barn 1 (the distance between two barns
is the smallest number of paths that one must traverse to get from
one to the other). Help Bessie figure out the best barn in which
to hide.

PROBLEM NAME: hideseek

INPUT FORMAT:

* Line 1: Two space-separated integers: N and M

* Lines 2..M+1: Line i+1 contains the endpoints for path i: A_i and
        B_i

SAMPLE INPUT (file hideseek.in):

6 7
3 6
4 3
3 2
1 3
1 2
2 4
5 2

INPUT DETAILS:

The farm layout is as follows:

                   1--2--5
                   | /|
                   |/ |
                   3--4
                   |
                   6

OUTPUT FORMAT:

* Line 1: On a single line, print three space-separated integers: the
        index of the barn farthest from barn 1 (if there are multiple
        such barns, print the smallest such index), the smallest
        number of paths needed to reach this barn from barn 1, and the
        number of barns with this number of paths.

SAMPLE OUTPUT (file hideseek.out):

4 2 3

OUTPUT DETAILS:

Barns 4, 5, and 6 are all a distance of 2 from barn 1. We choose barn 4
because it has the smallest index.

**********************************************************************
A题:

 SB最短路题。。SPFA或dij+heap

Problem 7: Cow Line [Jacob Steinhardt, 2009]

Farmer Johns N cows (conveniently numbered 1..N) are forming a
line. The line begins with no cows and then, as time progresses,
one by one, the cows join the line on the left or right side. Every
once in a while, some number of cows on the left or right side of
the line all leave the line to go graze in their favorite pasture.

FJ has trouble keeping track of all the cows in the line. Please
help him.

The cows enter the line in numerical order 1..N, and once a cow
leaves the line she never re-enters it. Your program will be given
S (1 <= S <= 100,000) input specifications; each appears on a single
line and is one of two types:

   * A cow enters the line (a parameter indicates whether on the
     left or right).

   * K cows leave the line from the left or right side (supplied
     parameters define both the number of cows and which side).

Input lines never request an operation that can not be performed.

After all the input lines have been processed, your program should
print the cows in the line in order from left to right. The final
line is guaranteed to be non-empty at the end of the input
specifications.

PROBLEM NAME: cline

INPUT FORMAT:

* Line 1: A single integer: S

* Lines 2..S+1: Line i+1 contains specification i in one of four
        formats:

   * A L -- a cow arrives on the Left of the line

   * A R -- a cow arrives on the Right of the line

   * D L K -- K cows depart the Left side of the line

   * D R K -- K cows depart the Right side of the line

SAMPLE INPUT (file cline.in):

10
A L
A L
A R
A L
D R 2
A R
A R
D L 1
A L
A R

OUTPUT FORMAT:

* Lines 1..??: Print the numbers of the cows in the line in order from
        left to right, one number per line.

SAMPLE OUTPUT (file cline.out):

7
2
5
6
8

OUTPUT DETAILS:

Input    Resulting Cow Line
A L      1
A L      2 1
A R      2 1 3
A L      4 2 1 3
D R 2    4 2
A R      4 2 5
A R      4 2 5 6
D L 1    2 5 6
A L      7 2 5 6
A R      7 2 5 6 8

**********************************************************************
B题

SB模拟题。。不多说。。

Problem 8: Cow Digit Game [Neal Wu, 2007]

Bessie is playing a number game against Farmer John, and she wants
you to help her achieve victory.

Game i starts with an integer N_i (1 <= N_i <= 1,000,000). Bessie
goes first, and then the two players alternate turns. On each turn,
a player can subtract either the largest digit or the smallest
non-zero digit from the current number to obtain a new number. For
example, from 3014 we may subtract either 1 or 4 to obtain either
3013 or 3010, respectively. The game continues until the number
becomes 0, at which point the last player to have taken a turn is
the winner.

Bessie and FJ play G (1 <= G <= 100) games. Determine, for each
game, whether Bessie or FJ will win, assuming that both play perfectly
(that is, on each turn, if the current player has a move that will
guarantee his or her win, he or she will take it).

Consider a sample game where N_i = 13. Bessie goes first and takes
3, leaving 10. FJ is forced to take 1, leaving 9. Bessie takes the
remainder and wins the game.

PROBLEM NAME: cdgame

INPUT FORMAT:

* Line 1: A single integer: G

* Lines 2..G+1: Line i+1 contains the single integer: N_i

SAMPLE INPUT (file cdgame.in):

2
9
10

OUTPUT FORMAT:

* Lines 1..G: Line i contains "YES" if Bessie can win game i, and "NO"
        otherwise.

SAMPLE OUTPUT (file cdgame.out):

YES
NO

OUTPUT DETAILS:

For the first game, Bessie simply takes the number 9 and wins.
For the second game, Bessie must take 1 (since she cannot take 0), and then
FJ can win by taking 9.

**********************************************************************
C题

一道博弈题。给你一个数N,你可以把N拆开取最大的数或最小的数(但不能是0) 取出后拿N-该数,作为新的数。你的对手同理。现在由你先选择,问你能否必胜。

我的做法:考虑一个数n的状态只有两种:一种是必胜态,一种是必败态;显然若数n-max或n-min都是必胜态,那么当前的状态n一定是必败态。于是可以递推求解。

Problem 9: Grazing2 [Osman Ay and Jacob Steinhardt, 2005]

Farmer John has N (2 <= N <= 1,500) prize milk cows conveniently
numbered 1..N. His newly-painted barn has S (N <= S <= 1,000,000)
stalls (conveniently numbered 1..S) in a single long line; each
stall is a unit distance from its neighboring stall(s).

The cows have made their way to the stalls for a rest; cow i is in
stall P_i. Antisocial as they are, the cows get grumpy if they are
situated in stalls very close to each other, so Farmer John wants
to move the cows to be as spread out as possible.

FJ wants to make sure that the N - 1 distances between adjacent
cows are as large as possible, and he would also like them to be
similar to each other (i.e., close to equi-distant spacing).

In particular, FJ would like all distances between adjacent cows
to be at most 1 different from (S - 1) / (N - 1), where integer
division is used. Moreover, he would like as many of these distances
as possible to be exactly equal to (S - 1) / (N - 1) [integer
division]. Thus, with four cows and eight stalls, one can place the
cows at positions 1, 3, 5, 8 or 1, 3, 6, 8 but not at 1, 2, 4, 7
or 1, 2, 4, 8.

Help FJ spread the cows as efficiently as possible by calculating
and reporting the minimum total distance that the cows have to move
in order to achieve proper spacing. Ignore the distance it takes
for a cow to enter or exit a stall.

PROBLEM NAME: graze2

INPUT FORMAT:

* Line 1: Two space-separated integers: N and S

* Lines 2..N+1: Line i+1 contains the single integer: P_i

SAMPLE INPUT (file graze2.in):

5 10
2
8
1
3
9

INPUT DETAILS:

               1   2   3   4   5   6   7   8   9  10
Cow Locs     | A | B | C | . | . | . | . | D | E | . |

OUTPUT FORMAT:

* Line 1: A single integer: the minimum total distance the cows have
        to travel. This number is guaranteed to be under 1,000,000,000
        (thus fitting easily into a signed 32-bit integer).

SAMPLE OUTPUT (file graze2.out):

4

OUTPUT DETAILS:

Cows move from stall 2 to 3, 3 to 5, and 9 to 10. The total distance
moved is 1 + 2 + 1 = 4. The final positions of the cows are in
stalls 1, 3, 5, 8, and 10.

                 1   2   3   4   5   6   7   8   9  10 
Init Stall     | A | B | C | . | . | . | . | D | E | . |
Final Stall    | A | . | B | . | C | . | . | D | . | E |
Distance moved | 0 | . | 1 | . | 2 | . | . | 0 | . | 1 | 

**********************************************************************
D题

一道动归题。N头头初始时在不同的位置上,现让每头牛的距离都尽量大(尽量等于 (s-1)/(n-1) ),问最小的移动步数。

这道题题目不难,但是题面读起来很费劲。。看懂意思之后,显然可以发现1和n的位置上一定有牛(为了保证牛距离尽量大),

那么设d = (s-1)/(p-1),r = (s-1)%(p-1)  则应该有 r个距离为d+1,其余为d。

     由此可设c(i,j)表示前i头牛中第i头牛在l(i,j) = d*(i-1) + j  (j<=r)  这个位置时所移动的最小步数,由于第i-1头牛只能有两种情况:l(i-1,j)[相当于l(i,j)-d] 和 l(i-1,j-1) [相当于l(i,j)-(d+1)]则有

     c(i,j) = min(c(i-1,j),c(i-1,j-1)) + abs(p[i]-l(i,j));

 

Codes:

  1 #include<queue>
  2 #include<vector>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<iostream>
  7 #include<algorithm>
  8 using namespace std;
  9 const int N = 20010;
 10 const int M = 50010;
 11 #define For(i,n) for(int i=1;i<=n;i++)
 12 #define Rep(i,l,r) for(int i=l;i<=r;i++)
 13 
 14 struct EDGE{
 15     int t,next;
 16 }E[M*2];
 17 bool exist[N];
 18 int cnt;
 19 int top,n,m,x,y,d[N];
 20 int head[N],stack[N],ans[N],Max;
 21 
 22 void makelist(int s,int t){
 23     E[cnt].t = t; E[cnt].next = head[s];
 24     head[s] = cnt++;
 25 }
 26 
 27 void init(){
 28     scanf("%d%d",&n,&m);
 29     memset(head,-1,sizeof(head));
 30     For(i,m){
 31         scanf("%d%d",&x,&y);
 32         makelist(x,y);
 33         makelist(y,x);
 34     }
 35 }
 36 
 37 void SPFA(){
 38     memset(d,0x7777777f,sizeof(d));
 39     stack[top=1,1] = 1;
 40     d[1] = 0;
 41     while(top){
 42         int u = stack[top--] , p = head[u];
 43         exist[u] = false;
 44         while(p!=-1){
 45             if(d[u]<d[E[p].t]-1){
 46                 d[E[p].t] = d[u] + 1;
 47                 if(!exist[E[p].t]){
 48                     stack[++top] = E[p].t;
 49                     exist[E[p].t] = true;
 50                 }
 51             }
 52             p = E[p].next;
 53         }
 54     }
 55     For(i,n)
 56       Max = max(Max,d[i]);
 57     For(i,n)
 58       if(d[i]==Max) ans[++ans[0]] = i;
 59     printf("%d %d %d\n",ans[1],Max,ans[0]);
 60 }
 61 
 62 int main(){
 63     init();
 64     SPFA();

 65     return 0;
 66 }
 67 
 68 ----------------------------------A-----------------------------------
 69 #include<queue>
 70 #include<vector>
 71 #include<cstdio>
 72 #include<cstdlib>
 73 #include<cstring>
 74 #include<iostream>
 75 #include<algorithm>
 76 using namespace std;
 77 #define For(i,n) for(int i=1;i<=n;i++)
 78 #define Rep(i,l,r) for(int i=l;i<=r;i++)
 79 
 80 int s,num;
 81 char ch1,ch2;
 82 
 83 int state[100010*2],start = 100010,endings=100010-1,now;
 84 
 85 void init(){
 86     scanf("%d",&s);
 87     For(i,s){
 88         scanf("\n");
 89         scanf("%c",&ch1);
 90         if(ch1==D) {
 91             scanf(" %c %d",&ch2,&num);
 92             if(ch2==R)    while(num--) state[endings--]=0;
 93             else            while(num--) state[start++] = 0;
 94         }else{
 95             scanf(" %c",&ch2);
 96             if(ch2==L)    state[--start] = ++now;
 97             else            state[++endings] = ++now;
 98         }
 99     }
100 }
101 
102 int main(){
103     init();
104     Rep(i,start,endings) printf("%d\n",state[i]);
105     return 0;
106 }
107 ------------------------------B---------------------------------------
108 #include<queue>
109 #include<vector>
110 #include<cstdio>
111 #include<cstdlib>
112 #include<cstring>
113 #include<iostream>
114 #include<algorithm>
115 using namespace std;
116 const int N = 1000001;
117 #define For(i,n) for(int i=1;i<=n;i++)
118 #define Rep(i,l,r) for(int i=l;i<=r;i++)
119 
120 bool can[N];
121 
122 int g,n;
123 
124 void solve (){
125     can [0] = false;
126     For(i,N-1){
127         int Min = 10, Max = 0;
128         int t = i;
129         while(t){
130             if (t%10!=0){
131                 Min = min(Min,t%10);
132                 Max = max(Max,t%10);
133             }
134             t/=10;
135         }
136         if(!can[i-Min]||!can[i-Max]) can[i] = true;
137         else                         can[i] = false;
138     }
139 }
140 
141 int main ()
142 {
143     solve();
144     scanf("%d",&g);
145     For(i,g){
146         scanf("%d",&n);
147         if(can[n]) puts("YES");
148         else       puts("NO");
149     }
150     return 0;
151 }
152 ---------------------------------C------------------------------------
153 #include<cmath>
154 #include<queue>
155 #include<vector>
156 #include<cstdio>
157 #include<cstring>
158 #include<cstdlib>
159 #include<iostream>
160 #include<algorithm>
161 using namespace std;
162 const int N = 1505;
163 const int inf = 214748367;
164 #define For(i,n) for(int i=1;i<=n;++i)
165 #define Rep(i,l,r) for(int i=l;i<=r;++i)
166 
167 int pos[N],dp[N][N],s,n,D,R;//前i头牛,第i头在L(i,j)位置处获得的最小步数。 
168 
169 void init(){
170     scanf("%d%d",&n,&s);
171     For(i,n) scanf("%d",pos + i);
172     sort(pos+1,pos+n+1); 
173     D = (s-1)/(n-1); R = (s-1)%(n-1);
174 }
175 
176 int move(int kth,int r){
177     return abs(pos[kth]-(D*(kth-1)+r+1));
178 } 
179 
180 void DP(){
181     fill(dp[1],dp[1]+R+1,inf);
182     dp[1][0] = move(1,0);
183     Rep(i,2,n){
184         fill(dp[i],dp[i]+R+1,inf);
185         dp[i][0] = dp[i-1][0] + move(i,0);
186         For(j,R){
187             dp[i][j] = min(dp[i-1][j] , dp[i-1][j-1]);
188             dp[i][j] += move(i,j); 
189         } 
190     }
191 }
192 
193 int main(){
194     init();
195     DP();
196     printf("%d\n",dp[n][R]);
197     return 0;
198 }
199 -----------------------------------D-----------------------------------
ABCD题代码