2014 ACM/ICPC--鞍山同步赛

2014-10-22 22:42:20

花了几个小时做了四道题。

 

B题大模拟...搞了很久,最后是把繁琐的STL全部去掉才过的TAT。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 using namespace std;
  5 typedef long long ll;
  6 
  7 int T,n,sz,altop,alpos;
  8 struct node{
  9     int p,w;
 10 }no[10010];
 11 
 12 void Move(int pos){
 13     if(alpos && alpos <= pos){
 14         if(alpos == pos)    alpos = 1;
 15         else    alpos++;
 16     }
 17     node tmp = no[pos];
 18     for(int i = pos; i > 1; --i)
 19         no[i] = no[i - 1];
 20     no[1] = tmp;
 21 }
 22 
 23 int main(){
 24     int a;
 25     char s[20];
 26     scanf("%d",&T);
 27     while(T--){
 28         memset(no,0,sizeof(no));
 29         altop = alpos = sz = 0;
 30         scanf("%d",&n);
 31         for(int Case = 1; Case <= n; ++Case){
 32             printf("Operation #%d: ", Case);
 33             scanf("%s",s);
 34             if(s[0] == 'A'){    //Add
 35                 scanf("%d",&a);
 36                 int flag = 0;
 37                 for(int i = 1; i <= sz; ++i) if(no[i].p == a){
 38                     flag = 1; break;
 39                 }
 40                 if(flag){ //已经存在
 41                     printf("same priority.\n");
 42                     continue;
 43                 }
 44                 no[++sz].p = a;
 45                 no[sz].w = 0;
 46                 printf("success.\n");
 47             }
 48             else if(s[0] == 'C' && s[1] == 'l'){  //Close
 49                 scanf("%d",&a);
 50                 int pos = 0;
 51                 for(int i = 1; i <= sz; ++i) if(no[i].p == a){
 52                     pos = i;
 53                     break;
 54                 }
 55                 if(pos == 0){ //不存在
 56                     printf("invalid priority.\n");
 57                     continue;
 58                 }
 59                 printf("close %d with %d.\n",no[pos].p,no[pos].w);
 60                 if(alpos > pos)   --alpos;
 61                 for(int i = pos + 1; i <= sz; ++i)
 62                     no[i - 1] = no[i];
 63                 --sz;
 64                 if(altop == a)      altop = alpos = 0;
 65             }
 66             else if(s[0] == 'C' && s[1] == 'h' && s[2] == 'a'){ //Chat
 67                 scanf("%d",&a);
 68                 if(sz == 0){
 69                     printf("empty.\n");
 70                     continue;
 71                 }
 72                 if(altop)    no[alpos].w += a;
 73                 else    no[1].w += a;
 74                 printf("success.\n");
 75             }
 76             else if(s[0] == 'R'){    //Rotate
 77                 scanf("%d",&a);
 78                 if(a < 1 || a > sz){
 79                     printf("out of range.\n");
 80                     continue;
 81                 }
 82                 Move(a);
 83                 printf("success.\n");
 84             }
 85             else if(s[0] == 'P'){    //Prior
 86                 if(sz == 0){
 87                     printf("empty.\n");
 88                     continue;
 89                 }
 90                 int pos = 1;
 91                 for(int i = 1; i <= sz; ++i) if(no[i].p > no[pos].p)
 92                     pos = i;
 93                 Move(pos);
 94                 printf("success.\n");
 95             }
 96             else if(s[0] == 'C' && s[1] == 'h' && s[2] == 'o'){ //Choose
 97                 scanf("%d",&a);
 98                 int pos = 0;
 99                 for(int i = 1; i <= sz; ++i) if(no[i].p == a){
100                     pos = i;
101                     break;
102                 }
103                 if(pos == 0){ //不存在
104                     printf("invalid priority.\n");
105                     continue;
106                 }
107                 Move(pos);
108                 printf("success.\n");
109             }
110             else if(s[0] == 'T'){ //Top
111                 scanf("%d",&a);
112                 int pos = 0;
113                 for(int i = 1; i <= sz; ++i) if(no[i].p == a){
114                     pos = i;
115                     break;
116                 }
117                 if(pos == 0){ //不存在
118                     printf("invalid priority.\n");
119                     continue;
120                 }
121                 altop = a;
122                 alpos = pos;
123                 printf("success.\n");
124             }
125             else{ //Untop
126                 if(alpos == 0){
127                     printf("no such person.\n");
128                     continue;
129                 }
130                 altop = alpos = 0;
131                 printf("success.\n");
132             }
133         }
134         if(alpos && no[alpos].w)
135             printf("Bye %d: %d\n",altop,no[alpos].w);
136         for(int i = 1; i <= sz; ++i) if(no[i].w && no[i].p != altop)
137             printf("Bye %d: %d\n",no[i].p,no[i].w);
138     }
139     return 0;
140 }
View Code

 

C题是个容斥,请教了bin神,呼呼思路精巧。

做法:(1)首先用容斥原理找出对于每个数,n个数中与其不互质 / 互质的数的个数。具体方法是将这个数唯一素数分解,然后用Dfs算出分解出的素数能组成哪些数(如:60分解出:2,3,5,三个素数,然后他们能组合出6,10,15,30这些数,开一个计数数组cnt,cnt[2、3、5、6、10、15、30] + 1),这样做的目的等会在容斥中就能理解。

   (2)对每个数容斥:将这个数分解素数,如15,能分解出3、5,那么与15不互质的数的个数就是:含因数3的数 + 含因数5的数 - 含因数3*5=15的数(因为15被算了两次),这样就能理解为什么(1)中这么处理了。(好吧,说的好乱,具体看代码吧)

 1 /*************************************************************************
 2     > File Name: 1003.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Wed 22 Oct 2014 02:03:15 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int T;
28 int a[300010];
29 int fac[100010];
30 int f[100],cnt;
31 ll ans,n;
32 
33 void Dfs(int p,int c,int val){
34     if(p > cnt){
35         if(c & 1) ans += fac[val] - 1;
36         else if(c > 0) ans -= fac[val] - 1;
37         return;
38     }
39     Dfs(p + 1,c,val);
40     Dfs(p + 1,c + 1,val * f[p]);
41 }
42 
43 void Dfs1(int p,int c,int val){
44     if(p > cnt){
45         if(c > 1) fac[val]++;
46         return;
47     }
48     Dfs1(p + 1,c,val);
49     Dfs1(p + 1,c + 1,val * f[p]);
50 }
51 
52 int main(){
53     int v,tmp;
54     scanf("%d",&T);
55     while(T--){
56         scanf("%I64d",&n);
57         memset(fac,0,sizeof(fac));
58         for(int i = 1; i <= n; ++i){
59             scanf("%d",a + i);
60             tmp = a[i];
61             v = sqrt(1.0 * tmp);
62             cnt = 0;
63             for(int j = 2; j <= v; ++j) if(tmp % j == 0){
64                 f[++cnt] = j;
65                 fac[j]++;
66                 while(tmp % j == 0) tmp /= j;
67             }
68             if(tmp != 1){
69                 f[++cnt] = tmp;
70                 fac[tmp]++;
71             }
72             Dfs1(1,0,1);
73         }
74         ll res = 0;
75         for(int i = 1; i <= n; ++i){
76             cnt = 0;
77             tmp = a[i];
78             v = sqrt(1.0 * tmp);
79             for(int j = 2; j <= v; ++j) if(tmp % j == 0){
80                 f[++cnt] = j;
81                 while(tmp % j == 0) tmp /= j;
82             }
83             if(tmp != 1){
84                 f[++cnt] = tmp;
85             }
86             ans = 0;
87             Dfs(1,0,1);
88             res += ans * (n - 1 - ans);    
89         }
90         printf("%I64d\n",n * (n - 1) * (n - 2) / (ll)6 - res / (ll)2);
91     }
92     return 0;
93 }
94         
View Code

 

D题就是维护一个(n-k)的框,框内答案为 a1^2+a2^2+...+an-k^2 - (a1+a2+...+an-k)^2 / (n-k)

 1 /*************************************************************************
 2     > File Name: 1004.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Wed 22 Oct 2014 11:26:09 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int T;
28 ll n,k,a[50010],sum[50010],sum2[50010];
29 
30 int main(){
31     scanf("%d",&T);
32     while(T--){
33         scanf("%I64d%I64d",&n,&k);
34         sum[0] = sum2[0] = 0;
35         for(int i = 1; i <= n; ++i){
36             scanf("%I64d",&a[i]);
37         }
38         sort(a + 1,a + n + 1);
39         for(int i = 1; i <= n; ++i){
40             sum[i] = sum[i - 1] + a[i];
41             sum2[i] = sum2[i - 1] + a[i] * a[i];
42         }
43         if(k == 0){
44             printf("%.10f\n",1.0 * sum2[n] - sum[n] * sum[n] / (1.0 * n));
45             continue;
46         }
47         if(n == k){
48             printf("0\n");
49             continue;
50         }
51         ll ans = (n - k) * sum2[n - k] - sum[n - k] * sum[n - k];
52         for(int i = n - k + 1; i <= n; ++i){
53             ans = min(ans,(n - k) * (sum2[i] - sum2[i - n + k]) -
54                     (sum[i] - sum[i - n + k]) * (sum[i] - sum[i - n + k]));
55         }
56         printf("%.10f\n",(double)ans / (1.0 * n - k));
57     }
58     return 0;
59 }
View Code

 

 

E题是个比较基础的DP,dp[i][j]表示长度为i,且第i位为j的最优解。dp[i][j] = max(dp[i - 1][k] + g[k][j])

 1 /*************************************************************************
 2     > File Name: 1005.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Wed 22 Oct 2014 03:07:01 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int T;
28 int n,m;
29 int g[55][55];
30 int a[105];
31 int dp[105][55];
32 
33 int main(){
34     scanf("%d",&T);
35     while(T--){
36         scanf("%d%d",&n,&m);
37         for(int i = 1; i <= m; ++i)
38             for(int j = 1; j <= m; ++j)
39                 scanf("%d",&g[i][j]);
40         for(int i = 1; i <= n; ++i)
41             scanf("%d",a + i);
42         for(int i = 1; i <= n; ++i)
43             for(int j = 1; j <= m; ++j)
44                 dp[i][j] = -INF;
45         if(a[1] == -1)
46             for(int j = 1; j <= m; ++j)
47                 dp[1][j] = 0;
48         else
49             dp[1][a[1]] = 0;
50         int ans = 0;
51         for(int i = 2; i <= n; ++i){
52             if(a[i] != -1){
53                 for(int k = 1; k <= m; ++k){
54                     dp[i][a[i]] = max(dp[i][a[i]],dp[i - 1][k] + g[k][a[i]]);
55                 }
56                 ans = max(ans,dp[i][a[i]]);
57             }
58             else{
59                 for(int j = 1; j <= m; ++j){
60                     for(int k = 1; k <= m; ++k){
61                         dp[i][j] = max(dp[i][j],dp[i - 1][k] + g[k][j]);
62                     }
63                     ans = max(ans,dp[i][j]);
64                 }
65             }
66         }
67         printf("%d\n",ans);
68     }
69     return 0;
70 }
View Code

 

posted @ 2014-10-22 23:08  Naturain  阅读(153)  评论(0)    收藏  举报