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 }
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 }
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 }