CF #277 div2

2014-11-12 20:24:14

总结:这场前三题比较顺利,D想到是树DP然后就不想搞了,作死搞了一发E....没搞出来orz....

A:简单数学

 1 /*************************************************************************
 2     > File Name: a.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Tue 11 Nov 2014 10:57:58 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 ll n;
28 
29 int main(){
30     scanf("%I64d",&n);
31     ll a = n / 2;
32     if(n % 2){
33         printf("%I64d\n",a - n);
34     }
35     else printf("%I64d\n",a);
36     return 0;
37 }
View Code

B:根据给出的B矩阵,只要发现bij为0,那么就把ai1、ai2、....ain和a1j、a2j、....amj都赋值为零,处理完所有bij=0的情况后,没有赋值过的aij都赋值为1(其实可以先初始化aij全1),最后判断一下每个bij=1的情况是否满足,只要检验ai1、ai2、...ain或a1j、a2j、....amj中是否至少有一个1即可。

 1 /*************************************************************************
 2     > File Name: b.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Tue 11 Nov 2014 11:05:44 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 n,m;
28 int b[105][105];
29 int a[105][105];
30 
31 int main(){
32     scanf("%d%d",&n,&m);
33     for(int i = 1; i <= n; ++i){
34         for(int j = 1; j <= m; ++j){
35             a[i][j] = 1;
36         }
37     }
38     for(int i = 1; i <= n; ++i){
39         for(int j = 1; j <= m; ++j){
40             scanf("%d",&b[i][j]);
41             if(b[i][j] == 0){
42                 for(int p = 1; p <= m; ++p) a[i][p] = 0;
43                 for(int p = 1; p <= n; ++p) a[p][j] = 0;
44             }
45         }
46     }
47     for(int i = 1; i <= n; ++i){
48         for(int j = 1; j <= m; ++j){
49             if(b[i][j] == 1){
50                 int flag = 0;
51                 for(int p = 1; p <= m; ++p) if(a[i][p]){
52                     flag = 1;
53                     break;
54                 }
55                 for(int p = 1; p <= n; ++p) if(a[p][j]){
56                     flag = 1;
57                     break;
58                 }
59                 if(flag == 0){
60                     printf("NO\n");
61                     return 0;
62                 }
63             }
64         }
65     }
66     printf("YES\n");
67     for(int i = 1; i <= n; ++i){
68         for(int j = 1; j < m; ++j){
69             printf("%d ",a[i][j]);
70         }
71         printf("%d\n",a[i][m]);
72     }
73     return 0;
74 }
View Code

C:一个贪心。首先考虑改左半部分和右半部分是等效的,那么首先判断p在左还是右,如果在左就处理左半部分,右同理。首先处理一下待处理的半部分每个字符转换所需的步数,比较两字符差值v和26-v,较小值就是改单个字符所需步数。知道了所需处理的字符位置和所需步数,就好处理了。

 1 /*************************************************************************
 2     > File Name: c.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Tue 11 Nov 2014 11:19:39 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 n,p,mid;
28 char s[100010];
29 int f[100010];
30 
31 int Solve(int a,int b){
32     int ans = 0,fmax = -INF,fmin = INF;
33     for(int i = a; i <= b; ++i){
34         int v = abs(s[i] - s[n + 1 - i]);
35         f[i] = min(v,26 - v);
36         if(f[i]){
37             fmax = max(fmax,i);
38             fmin = min(fmin,i);
39             ans += f[i];
40         }
41     }
42     if(fmax == -INF) fmax = fmin = p;
43     ans += fmax - fmin + min(abs(fmax - p),abs(fmin - p));
44     return ans;
45 }
46 
47 int main(){
48     scanf("%d%d",&n,&p);
49     scanf("%s",s + 1);
50     mid = (n + 1) / 2;
51     if(p <= mid)
52         printf("%d\n",Solve(1,mid));
53     else
54         printf("%d\n",Solve(mid + 1,n));
55     return 0;
56 }

D:先将所有数的数值排个序,然后扫描每个点,并且以其为起点(做树根),向右扫描,把比它大<=d的点都加入树中,获得一颗树,然后求包含根节点的路径方案总数,可用dp解决。基本思路:所有子节点方案数+1,相乘起来即可。

  1 /*************************************************************************
  2     > File Name: d.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com
  5     > Created Time: Tue 11 Nov 2014 11:47:55 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 const int maxn = 2010;
 27 const long long mod = 1000000007;
 28 
 29 int d,n,vis[maxn];
 30 int first[maxn],next[maxn * 2],ver[maxn * 2],ecnt;
 31 int f1[maxn],n1[maxn * 2],v1[maxn * 2],e1;
 32 ll ans;
 33 
 34 int cop[maxn];
 35 struct node{
 36     int val,pos;
 37     bool operator < (const node &b) const{
 38         return val < b.val;
 39     }
 40 }t[maxn];
 41 
 42 void Init(){
 43     memset(first,-1,sizeof(first));
 44     ecnt = 0;
 45 }
 46 
 47 void Init1(){
 48     memset(f1,-1,sizeof(f1));
 49     e1 = 0;
 50 }
 51 
 52 void Add_edge(int u,int v){
 53     next[++ecnt] = first[u];
 54     ver[ecnt] = v;
 55     first[u] = ecnt;
 56 }
 57 
 58 void Add_edge1(int u,int v){
 59     n1[++e1] = f1[u];
 60     v1[e1] = v;
 61     f1[u] = e1;
 62 }
 63 
 64 ll Dfs(int p,int fa){
 65     ll res = 1;
 66     for(int i = f1[p]; i != -1; i = n1[i]){
 67         int v = v1[i];
 68         if(v == fa) continue;
 69         res = (res * (Dfs(v,p) + 1)) % mod;
 70     }
 71     return res;
 72 }
 73 
 74 int main(){
 75     int a,b;
 76     Init();
 77     scanf("%d%d",&d,&n);
 78     for(int i = 1; i <= n; ++i){
 79         scanf("%d",&t[i].val);
 80         t[i].pos = i;
 81     }
 82     sort(t + 1,t + n + 1);
 83     for(int i = 1; i <= n; ++i){
 84         cop[t[i].pos] = i;
 85     }
 86     for(int i = 1; i < n; ++i){
 87         scanf("%d%d",&a,&b);
 88         Add_edge(a,b);
 89         Add_edge(b,a);
 90     }
 91     ll ans = 0;
 92     for(int i = 1; i <= n; ++i){
 93         Init1();
 94         int flag;
 95         for(int j = i; j <= n && t[j].val - t[i].val <= d; ++j){
 96             flag = j;
 97             for(int k = first[t[j].pos]; k != -1; k = next[k]){
 98                 int v = ver[k];
 99                 if(cop[v] >= i && t[cop[v]].val - t[i].val <= d){
100                     Add_edge1(t[j].pos,v);
101                 }
102             }
103         }
104         memset(vis,0,sizeof(vis));
105         ans = (ans + Dfs(t[i].pos,0)) % mod;
106     }
107     printf("%I64d\n",ans);
108     return 0;
109 }

 

posted @ 2014-11-12 20:41  Naturain  阅读(123)  评论(0编辑  收藏  举报