Codeforces Round #257 (Div. 2) 前四题

A - Jzzhu and Children

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<string>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 
 9 using namespace std;
10 
11 #define ll long long
12 #define eps 1e-8
13 #define mod 1000007
14 #define mnx 5010
15 
16 struct peo{
17     int v, id;
18 }a[mnx];
19 int main(){
20     int n, m;
21     scanf( "%d%d", &n, &m );
22     queue<peo> que;
23     for( int i = 1; i <= n; i++ ){
24         scanf( "%d", &a[i].v );
25         a[i].id = i;
26         que.push(a[i]);
27     }
28     while( que.size() != 1 ){
29         peo tmp = que.front();  
30         que.pop();
31         if( tmp.v > m ){
32             tmp.v -= m;
33             que.push(tmp); 
34         }
35     }
36     peo tmp = que.front();
37     printf( "%d\n", tmp.id );
38     return 0;
39 }
View Code

 

B - Jzzhu and Sequences

f[i] = f[i-1] + f[i+1] 即 f[i+1] = f[i] - f[i-1] 则 f[i+2] = f[i+1] - f[i] = f[i] - f[i-1] - f[i] = - f[i-1],即 f[i+3] = -f[i]

可以得到 f[i+6] = -f[i+3] = f[i] 循环节是6

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<string>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 
 9 using namespace std;
10 
11 #define ll long long
12 #define eps 1e-8
13 #define mod  1000000007
14 #define mnx 5010
15 
16 ll a[mnx];
17 int main(){
18     ll x, y, n;
19     cin >> x >> y >> n;
20     a[0] = x, a[1] = y, a[2] = a[1] - a[0];
21     a[3] = -x, a[4] = -y, a[5] = -a[2];
22     n = ( n - 1 ) % 6;
23     ll ans = a[n];
24     while( ans < 0 ){
25         ans += mod;
26     }
27     cout << ans % mod <<endl;
28     return 0;
29 }
View Code

 

C - Jzzhu and Chocolate

n*m巧克力,横切和纵切总共k刀,求最小矩形的最大面积是多少。。因为如果横切和纵切混着来,巧克力就会越分越多,所以沿着其中一条边切,如果这一条边不能再切了才去切另外一条,这样能够保证k刀下来,最小巧克力的面积达到最大。。沿着两条边都试切一下,取最大值

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<string>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 
 9 using namespace std;
10 
11 #define ll long long
12 #define eps 1e-8
13 #define mod  1000000007
14 #define mnx 5010
15 
16 int main(){
17     ll n, m, k;
18     cin >> n >> m >> k;
19     ll k1 = k;
20     ll sum = n + m - 2, ans, ans1, sum1 = n * m;
21     if( k > sum ){
22         puts( "-1" );
23     }   
24     else if( k == sum ){
25         puts( "1" );
26     }
27     else{
28         if( k + 1 <= n ){
29             ans = n / ( k + 1 ) * m;    
30         }
31         if( k + 1 > n ){
32             k -= n - 1;
33             ans = m / ( k + 1 ); 
34         }
35         swap( n, m );
36         if( k1 + 1 <= n ){
37             ans1 = n / ( k1 + 1 ) * m;  
38         }
39         if( k1 + 1 > n ){
40             k1 -= n - 1;
41             ans1 = m / ( k1 + 1 ); 
42         }
43         cout << max( ans, ans1 ) <<endl;
44     }
45     return 0;
46 }
View Code

 

D - Jzzhu and Cities

最短路。。有n个城市,1是首都,m条路( u, v, c1 ),还有k条火车路线( 1, v, c2 ),问你最多能够删除多少条火车路,使得从1到所有城市的最短路不变。。首先以1为起点对m条路进行dij(),然后k条火车路线( 1, v, c2 ),如果c2 >= dis[v] 的话,这条路线就可以删去;但是如果c2 < dis[v]的话,就要讨论一下能不能删除: 假如dis[u] = 100 , dis[v] = 100, 有一条路( u, v, 60 ), 火车路线( 1, u, 10 ), ( 1, v, 80 ),虽然两条火车路线都比dis[]要短,但是( 1, v, 80 )这一条是可以删除的,因为从( 1, u, 10 )这条线加上( u, v, 60 )距离小于( 1, v, 80 )。所以要对c2 < dis[v]的点再dij() 一次

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<string>
  6 #include<queue>
  7 #include<cmath>
  8 
  9 using namespace std;
 10 
 11 #define mnx 800500
 12 #define ll long long
 13 #define inf 0x3f3f3f3f
 14 #define lson l, m, rt << 1
 15 #define rson m+1, r, rt << 1 | 1
 16 
 17 int vv[mnx], first[mnx], nxt[mnx], e, ans;
 18 ll cost[mnx], dis[mnx], dis2[mnx];
 19 bool vis[mnx], used[mnx], in[mnx];
 20 int n, m, k;
 21 void init(){
 22     memset( first, -1, sizeof(first) );
 23     memset( dis, 0x3f, sizeof(dis) );
 24     memset( vis, 0, sizeof(vis) );
 25     e = ans = 0;
 26 }
 27 void add( int u, int v, int c ){
 28     vv[e] = v, nxt[e] = first[u];
 29     cost[e] = c, first[u] = e++;
 30 }
 31 struct edge{
 32     int u;
 33     ll d;
 34     bool operator < ( const edge & b ) const{
 35         return d > b.d;
 36     }
 37 };
 38 void dij(){
 39     priority_queue<edge> que;
 40     dis[1] = 0;
 41     edge tmp;
 42     tmp.u = 1, tmp.d = 0;
 43     que.push( tmp );
 44     while( !que.empty() ){
 45         tmp = que.top(); que.pop();
 46         int u = tmp.u;
 47         if( vis[u] ) continue;
 48         vis[u] = 1;
 49         for( int i = first[u]; i != -1; i = nxt[i] ){
 50             int v = vv[i]; ll c = cost[i];
 51             if( dis[v] > dis[u] + c ){
 52                 dis[v] = dis[u] + c;
 53                 edge q;
 54                 q.u = v, q.d = dis[v];
 55                 que.push( q );
 56             }
 57         }
 58     }
 59 }
 60 void dij2(){
 61     memset( vis, 0, sizeof(vis) );
 62     priority_queue<edge> que;
 63     for( int i = 2; i <= n; i++ ){
 64         if( dis2[i] < dis[i] ){
 65             edge q;
 66             q.u = i, q.d = dis2[i];
 67             que.push( q );
 68         }
 69     }
 70     while( !que.empty() ){
 71         edge q = que.top(); que.pop();
 72         int u = q.u;
 73         if( vis[u] ) continue;
 74         vis[u] = 1;
 75         for( int i = first[u]; i != -1; i = nxt[i] ){
 76             int v = vv[i]; ll c = cost[i];
 77             if( dis2[v] >= dis2[u] + c ){
 78                 dis2[v] = dis2[u] + c;
 79                 if( used[v] ){
 80                     ans++;
 81                     used[v] = 0;
 82                 } 
 83                 edge q2;
 84                 q2.u = v, q2.d = dis2[v];
 85                 que.push( q2 );
 86             }
 87         }
 88     }
 89 }
 90 int main(){
 91     init();
 92     scanf( "%d%d%d", &n, &m, &k );
 93     for( int i = 0; i < m; i++ ){
 94         int u, v; ll c;
 95         scanf( "%d%d%I64d", &u, &v, &c );
 96         add( u, v, c );
 97         add( v, u, c ); 
 98     }
 99     dij();
100     memcpy( dis2, dis, sizeof(dis2) );
101     memset( used, 0, sizeof(used) );
102     for( int i = 0; i < k; i++ ){
103         int v; ll c;
104         scanf( "%d%I64d", &v, &c );
105         if( dis2[v] <= c ) ans++;
106         else{
107             dis2[v] = c;
108             if( used[v] ) ans++;
109             used[v] = 1;
110         }
111     }
112     dij2();
113     printf( "%d\n", ans );
114     return 0;
115 }
View Code
posted @ 2014-07-21 18:11  L__J  阅读(157)  评论(0编辑  收藏  举报