2010TianjinRegional 部分题解

比赛链接:http://acm.hust.edu.cn/vjudge/contest/129879#overview

A.Arranging Your Team

题意:给你23个人的姓名,分数,位置。让你从这23个人里挑选出一个4-4-2-1的阵容,每两个人之间会相互影响,取决于一个值。求一种挑选方法,使得整个分数最大。

4-4-2-1,每个人的职责不一样,这个复杂度分析起来挺玄学的。暴力搜索,分职责去挑选,最终挑选完毕统计结果即可。也可以用状压直接枚举,复杂度应该是一样的。注意这里应当把姓名离散化,否则会TLE(不离散化大概一个样例要跑5s,不要问我怎么知道的…)

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <algorithm>
 18 #include <iostream>
 19 #include <iomanip>
 20 #include <cstring>
 21 #include <climits>
 22 #include <complex>
 23 #include <fstream>
 24 #include <cassert>
 25 #include <cstdio>
 26 #include <bitset>
 27 #include <vector>
 28 #include <deque>
 29 #include <queue>
 30 #include <stack>
 31 #include <ctime>
 32 #include <set>
 33 #include <map>
 34 #include <cmath>
 35 using namespace std;
 36 #define fr first
 37 #define sc second
 38 #define cl clear
 39 #define BUG puts("here!!!")
 40 #define W(a) while(a--)
 41 #define pb(a) push_back(a)
 42 #define Rint(a) scanf("%d", &a)
 43 #define Rll(a) scanf("%I64d", &a)
 44 #define Rs(a) scanf("%s", a)
 45 #define Cin(a) cin >> a
 46 #define FRead() freopen("in", "r", stdin)
 47 #define FWrite() freopen("out", "w", stdout)
 48 #define Rep(i, len) for(int i = 0; i < (len); i++)
 49 #define For(i, a, len) for(int i = (a); i < (len); i++)
 50 #define Cls(a) memset((a), 0, sizeof(a))
 51 #define Clr(a, x) memset((a), (x), sizeof(a))
 52 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 53 #define lrt rt << 1
 54 #define rrt rt << 1 | 1
 55 #define pi 3.14159265359
 56 #define RT return
 57 #define lowbit(x) x & (-x)
 58 #define onecnt(x) __builtin_popcount(x)
 59 typedef long long LL;
 60 typedef long double LD;
 61 typedef unsigned long long ULL;
 62 typedef pair<int, int> pii;
 63 typedef pair<string, int> psi;
 64 typedef pair<LL, LL> pll;
 65 typedef map<string, int> msi;
 66 typedef vector<int> vi;
 67 typedef vector<LL> vl;
 68 typedef vector<vl> vvl;
 69 typedef vector<bool> vb;
 70 
 71 const int maxn = 33;
 72 typedef struct Node {
 73     int id;
 74     string name;
 75     int s;
 76     int t;
 77 }Node;
 78 Node fuck;
 79 int n, m;
 80 string tmp;
 81 int ret;
 82 vector<Node> peo[6];
 83 int G[maxn][maxn];
 84 vector<int> ans;
 85 int score[maxn];
 86 map<string, int> ns;
 87 
 88 int get() {
 89     if(tmp[0] == 'g') return 1;
 90     else if(tmp[0] == 'd') return 2;
 91     else if(tmp[0] == 'm') return 3;
 92     else if(tmp[0] == 's') return 4;
 93 }
 94 
 95 void dfs1(int cur, int cnt);
 96 void dfs2(int cur, int cnt);
 97 void dfs3(int cur, int cnt);
 98 void dfs4(int cur, int cnt);
 99 
100 void dfs1(int cur, int cnt) {
101     if(cnt == 1) {
102         dfs2(-1, 0);
103         return;
104     }
105     For(i, cur+1, peo[1].size()) {
106         ans.push_back(peo[1][i].id);
107         dfs1(i, cnt+1);
108         ans.pop_back();
109     }
110 }
111 
112 void dfs2(int cur, int cnt) {
113     if(cnt == 4) {
114         dfs3(-1, 0);
115         return;
116     }
117     For(i, cur+1, peo[2].size()) {
118         ans.push_back(peo[2][i].id);
119         dfs2(i, cnt+1);
120         ans.pop_back();
121     }
122 }
123 
124 void dfs3(int cur, int cnt) {
125     if(cnt == 4) {
126         dfs4(-1, 0);
127         return;
128     }
129     For(i, cur+1, peo[3].size()) {
130         ans.push_back(peo[3][i].id);
131         dfs3(i, cnt+1);
132         ans.pop_back();
133     }
134 }
135 
136 void dfs4(int cur, int cnt) {
137     if(cnt == 2) {
138         int sum = 0;
139         Rep(i, ans.size()) {
140             For(j, i+1, ans.size()) {
141                 sum += G[ans[i]][ans[j]];
142             }
143             sum += score[ans[i]];
144         }
145         ret = max(ret, sum);
146         return;
147     }
148     For(i, cur+1, peo[4].size()) {
149         ans.push_back(peo[4][i].id);
150         dfs4(i, cnt+1);
151         ans.pop_back();
152     }
153 }
154 
155 int main() {
156     // FRead();
157     int id = 1;
158     while(cin >> fuck.name >> fuck.s >> tmp) {
159         ret = -0x7f7f7f; Cls(score); Cls(G);
160         For(i, 1, 5) peo[i].clear(); id = 1; ns.clear(); ans.clear();
161 
162         fuck.t = get(); ns[fuck.name] = id++;
163         score[id-1] = fuck.s;
164         fuck.id = id - 1;
165         peo[fuck.t].pb(fuck);
166         For(i, 2, 24) {
167             cin >> fuck.name >> fuck.s >> tmp;
168             fuck.t = get(); ns[fuck.name] = id++;
169             score[id-1] = fuck.s;
170             fuck.id = id - 1;
171             peo[fuck.t].pb(fuck);
172         }
173         Rint(m);
174         string a, b;
175         int sc;
176         Rep(i, m) {
177             cin >> a >> b >> sc;
178             G[ns[a]][ns[b]] = G[ns[b]][ns[a]] = sc;
179         }
180         if(peo[1].size()<1||peo[2].size()<4||peo[3].size()<4||peo[4].size()<2) {
181             printf("impossible
");
182             continue;
183         }
184         dfs1(-1, 0);
185         printf("%d
", ret);
186     }
187     RT 0;
188 }
A

C.Card Game

题意:给n个字符串,让它们两两配对,比如字符串i和j,让i和j的翻转重叠的最多。

根据i,j的重叠字符数量建图G(i,j),跑KM。模版题,注意别忘了初始化nx, ny…

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <algorithm>
 18 #include <iostream>
 19 #include <iomanip>
 20 #include <cstring>
 21 #include <climits>
 22 #include <complex>
 23 #include <fstream>
 24 #include <cassert>
 25 #include <cstdio>
 26 #include <bitset>
 27 #include <vector>
 28 #include <deque>
 29 #include <queue>
 30 #include <stack>
 31 #include <ctime>
 32 #include <set>
 33 #include <map>
 34 #include <cmath>
 35 using namespace std;
 36 #define fr first
 37 #define sc second
 38 #define cl clear
 39 #define BUG puts("here!!!")
 40 #define W(a) while(a--)
 41 #define pb(a) push_back(a)
 42 #define Rint(a) scanf("%d", &a)
 43 #define Rll(a) scanf("%I64d", &a)
 44 #define Rs(a) scanf("%s", a)
 45 #define Cin(a) cin >> a
 46 #define FRead() freopen("in", "r", stdin)
 47 #define FWrite() freopen("out", "w", stdout)
 48 #define Rep(i, len) for(int i = 0; i < (len); i++)
 49 #define For(i, a, len) for(int i = (a); i < (len); i++)
 50 #define Cls(a) memset((a), 0, sizeof(a))
 51 #define Clr(a, x) memset((a), (x), sizeof(a))
 52 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 53 #define lrt rt << 1
 54 #define rrt rt << 1 | 1
 55 #define pi 3.14159265359
 56 #define RT return
 57 #define lowbit(x) x & (-x)
 58 #define onecnt(x) __builtin_popcount(x)
 59 typedef long long LL;
 60 typedef long double LD;
 61 typedef unsigned long long ULL;
 62 typedef pair<int, int> pii;
 63 typedef pair<string, int> psi;
 64 typedef pair<LL, LL> pll;
 65 typedef map<string, int> msi;
 66 typedef vector<int> vi;
 67 typedef vector<LL> vl;
 68 typedef vector<vl> vvl;
 69 typedef vector<bool> vb;
 70 
 71 /*  KM算法
 72  *   复杂度O(nx*nx*ny)
 73  *  求最大权匹配
 74  *   若求最小权匹配,可将权值取相反数,结果取相反数
 75  *  点的编号从0开始
 76  */
 77 const int maxn = 310;
 78 const int inf = 0x3f3f3f3f;
 79 int nx,ny;//两边的点数,注意修改
 80 int G[maxn][maxn];//二分图描述
 81 int linker[maxn],lx[maxn],ly[maxn];//y中各点匹配状态,x,y中的点标号
 82 int slack[maxn];
 83 bool visx[maxn],visy[maxn];
 84 
 85 bool dfs(int x) {
 86     visx[x] = true;
 87     for(int y = 0; y < ny; y++) {
 88         if(visy[y])continue;
 89         int tmp = lx[x] + ly[y] - G[x][y];
 90         if(tmp == 0) {
 91             visy[y] = true;
 92             if(linker[y] == -1 || dfs(linker[y])) {
 93                 linker[y] = x;
 94                 return true;
 95             }
 96         }
 97         else if(slack[y] > tmp)
 98             slack[y] = tmp;
 99     }
100     return false;
101 }
102 int km() {
103     memset(linker,-1,sizeof(linker));
104     memset(ly,0,sizeof(ly));
105     for(int i = 0;i < nx;i++) {
106         lx[i] = -inf;
107         for(int j = 0;j < ny;j++)
108             if(G[i][j] > lx[i])
109                 lx[i] = G[i][j];
110     }
111     for(int x = 0;x < nx;x++) {
112         for(int i = 0;i < ny;i++)
113             slack[i] = inf;
114         while(true) {
115             memset(visx,false,sizeof(visx));
116             memset(visy,false,sizeof(visy));
117             if(dfs(x))break;
118             int d = inf;
119             for(int i = 0;i < ny;i++)
120                 if(!visy[i] && d > slack[i])
121                     d = slack[i];
122             for(int i = 0;i < nx;i++)
123                 if(visx[i])
124                     lx[i] -= d;
125             for(int i = 0;i < ny;i++) {
126                 if(visy[i])ly[i] += d;
127                 else slack[i] -= d;
128             }
129         }
130     }
131     int res = 0;
132     for(int i = 0;i < ny;i++)
133         if(linker[i] != -1)
134             res += G[linker[i]][i];
135     return res;
136 }
137 
138 int n;
139 string s[maxn];
140 
141 int get(string a, string b) {
142     int ret = 0;
143     int i, j;
144     for(i = a.length() - 1, j = 0; a[i] && b[j]; i--, j++) {
145         if(a[i] != b[j]) return ret;
146         else ret++;
147     }
148     return ret;
149 }
150 
151 int main() {
152     // FRead();
153     while(~Rint(n)) {
154         Cls(G);
155         nx = ny = n;
156         Rep(i, n) cin >> s[i];
157         Rep(i, n) {
158             Rep(j, n) {
159                 if(i == j) continue;
160                 G[i][j] = get(s[i], s[j]);
161             }
162         }
163         printf("%d
", km());
164     }
165     RT 0;
166 }
C

D.Delta Wave

题意:在一个网格上,若限定每步只能向右移动一格,可以右上,右下,横向,向右,并禁止移动到以下的地方,则以这种走法移动步从到的可能形成的路径的总数为的默慈金数。

大数+默慈金数,直接搬了http://blog.csdn.net/acdreamers/article/details/41213667

 1 //默慈金数
 2 // Mn = ∑C(n, 2*i) Catalan(i)
 3 import java.math.*;
 4 import java.util.*;
 5 
 6 public class Main {
 7     
 8     public static final int N = 10005;
 9     public static final BigInteger MOD = BigInteger.valueOf(10).pow(100);
10     public static BigInteger ans[] = new BigInteger[N];
11     public static void Init(){
12         ans[1] = BigInteger.valueOf(1);
13         ans[2] = BigInteger.valueOf(2);
14         for(int i = 3; i < N; i++){
15             BigInteger a = ans[i - 1].multiply((BigInteger.valueOf(2).multiply(BigInteger.valueOf(i)).add(BigInteger.valueOf(1))));
16             BigInteger b = ans[i - 2].multiply((BigInteger.valueOf(3).multiply(BigInteger.valueOf(i)).subtract(BigInteger.valueOf(3))));
17             ans[i] = (a.add(b)).divide(BigInteger.valueOf(i).add((BigInteger.valueOf(2))));
18         }
19     }
20     
21     public static void main(String[] args){
22         Init();
23         Scanner cin = new Scanner(System.in);
24         while(cin.hasNext()){
25             int n = cin.nextInt();
26             System.out.println(ans[n].mod(MOD));
27         }
28     }
29 }
D

E.Encoded Barcodes

题意:给一个字典和m个条形码,条形码的条形有粗有细,在一个阈值外是粗,阈值内是细。把条形码转换成字符串后是字典中的多少个字符串的前缀,统计m个条形码的总和。

字典树,条形码区分01的时候是和平均数做的比较,比平均数大是1,小是0。不能用cin,会TLE。

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <algorithm>
 18 #include <iostream>
 19 #include <iomanip>
 20 #include <cstring>
 21 #include <climits>
 22 #include <complex>
 23 #include <fstream>
 24 #include <cassert>
 25 #include <cstdio>
 26 #include <bitset>
 27 #include <vector>
 28 #include <deque>
 29 #include <queue>
 30 #include <stack>
 31 #include <ctime>
 32 #include <set>
 33 #include <map>
 34 #include <cmath>
 35 using namespace std;
 36 #define fr first
 37 #define sc second
 38 #define cl clear
 39 #define BUG puts("here!!!")
 40 #define W(a) while(a--)
 41 #define pb(a) push_back(a)
 42 #define Rint(a) scanf("%d", &a)
 43 #define Rll(a) scanf("%I64d", &a)
 44 #define Rs(a) scanf("%s", a)
 45 #define Cin(a) cin >> a
 46 #define FRead() freopen("in", "r", stdin)
 47 #define FWrite() freopen("out", "w", stdout)
 48 #define Rep(i, len) for(int i = 0; i < (len); i++)
 49 #define For(i, a, len) for(int i = (a); i < (len); i++)
 50 #define Cls(a) memset((a), 0, sizeof(a))
 51 #define Clr(a, x) memset((a), (x), sizeof(a))
 52 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 53 #define lrt rt << 1
 54 #define rrt rt << 1 | 1
 55 #define pi 3.14159265359
 56 #define RT return
 57 #define lowbit(x) x & (-x)
 58 #define onecnt(x) __builtin_popcount(x)
 59 typedef long long LL;
 60 typedef long double LD;
 61 typedef unsigned long long ULL;
 62 typedef pair<int, int> pii;
 63 typedef pair<string, int> psi;
 64 typedef pair<LL, LL> pll;
 65 typedef map<string, int> msi;
 66 typedef vector<int> vi;
 67 typedef vector<LL> vl;
 68 typedef vector<vl> vvl;
 69 typedef vector<bool> vb;
 70 
 71 typedef struct Node {
 72     int cnt;
 73     Node* next[26];
 74     Node() {
 75         cnt = 0;
 76         Rep(i, 26) next[i] = NULL;
 77     }
 78 }Node;
 79 
 80 Node* rt;
 81 Node memory[110000];
 82 int mcnt;
 83 
 84 void insert(Node* p, string str) {
 85     for(int i = 0; str[i]; i++) {
 86         if(p->next[str[i]-'a'] == NULL) {
 87             p->next[str[i]-'a'] = &memory[mcnt++];
 88         }
 89         p = p->next[str[i]-'a'];
 90         p->cnt++;
 91     }
 92 }
 93 
 94 int find(Node* p, string str) {
 95     for(int i = 0; str[i]; i++) {
 96         int t = str[i] - 'a';
 97         if(p->next[t] == NULL) return 0;
 98         p = p->next[t];
 99     }
100     return p->cnt;
101 }
102 
103 int n, m, k;
104 
105 inline bool scan_lf(double &num) {
106     char in;double Dec=0.1;
107     bool IsN=false,IsD=false;
108     in=getchar();
109     if(in==EOF) return false;
110     while(in!='-'&&in!='.'&&(in<'0'||in>'9'))
111             in=getchar();
112     if(in=='-'){IsN=true;num=0;}
113     else if(in=='.'){IsD=true;num=0;}
114     else num=in-'0';
115     if(!IsD){
116             while(in=getchar(),in>='0'&&in<='9'){
117                     num*=10;num+=in-'0';}
118     }
119     if(in!='.'){
120             if(IsN) num=-num;
121             return true;
122     }else{
123             while(in=getchar(),in>='0'&&in<='9'){
124                     num+=Dec*(in-'0');Dec*=0.1;
125             }
126     }
127     if(IsN) num=-num;
128     return true;
129 }
130 
131 string get(int k) {
132     string ret;
133     Rep(i, k) {
134         double a[10];
135         double sum = 0.0;
136         Rep(j, 8) {
137             scan_lf(a[j]);
138             sum += a[j];
139         }
140         sum /= 8;
141         int ch = 0;
142         Rep(j, 8) {
143             ch <<= 1;
144             ch |= (a[j] > sum);
145         }
146         ret.push_back(ch);
147     }
148     return ret;
149 }
150 
151 int main() {
152     // FRead();
153     string tmp;
154     while(cin >> n >> m) {
155         mcnt = 0; Cls(memory);
156         rt = &memory[mcnt++];
157         // rt = new Node();
158         Rep(i, n) {
159             cin >> tmp;
160             insert(rt, tmp);
161         }
162         int ret = 0;
163         W(m) {
164             Rint(k);
165             tmp = get(k);
166             ret += find(rt, tmp);
167         }
168         printf("%d
", ret);
169     }
170     RT 0;
171 }
E

I.I'm Telling the Truth

题意:n个人说自己的名次区间,其中有人是说谎的。求说谎人最少的情况,输出说真话的人数,要反字典序(最大的几个)。

贪心无法得到规定的序列,应该按区间的左右端点建二分图,跑匈牙利算法。

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <algorithm>
 18 #include <iostream>
 19 #include <iomanip>
 20 #include <cstring>
 21 #include <climits>
 22 #include <complex>
 23 #include <cassert>
 24 #include <cstdio>
 25 #include <bitset>
 26 #include <vector>
 27 #include <deque>
 28 #include <queue>
 29 #include <stack>
 30 #include <ctime>
 31 #include <set>
 32 #include <map>
 33 #include <cmath>
 34 using namespace std;
 35 #define fr first
 36 #define sc second
 37 #define cl clear
 38 #define BUG puts("here!!!")
 39 #define W(a) while(a--)
 40 #define pb(a) push_back(a)
 41 #define Rint(a) scanf("%d", &a)
 42 #define Rs(a) scanf("%s", a)
 43 #define Cin(a) cin >> a
 44 #define FRead() freopen("in", "r", stdin)
 45 #define FWrite() freopen("out", "w", stdout)
 46 #define Rep(i, len) for(int i = 0; i < (len); i++)
 47 #define For(i, a, len) for(int i = (a); i < (len); i++)
 48 #define Cls(a) memset((a), 0, sizeof(a))
 49 #define Clr(a, x) memset((a), (x), sizeof(a))
 50 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 51 #define lrt rt << 1
 52 #define rrt rt << 1 | 1
 53 #define pi 3.14159265359
 54 #define RT return
 55 #define lowbit(x) x & (-x)
 56 #define onenum(x) __builtin_popcount(x)
 57 typedef long long LL;
 58 typedef long double LD;
 59 typedef unsigned long long ULL;
 60 typedef pair<int, int> pii;
 61 typedef pair<string, int> psi;
 62 typedef pair<LL, LL> pll;
 63 typedef map<string, int> msi;
 64 typedef vector<int> vi;
 65 typedef vector<LL> vl;
 66 typedef vector<vl> vvl;
 67 typedef vector<bool> vb;
 68 
 69 const int maxn = 110;
 70 const int maxm = 200100;
 71 int x[maxn], y[maxn], linker[maxm];
 72 int n, ret;
 73 int ok[maxn];
 74 bool vis[maxm];
 75 
 76 bool dfs(int u) {
 77     For(i, x[u], y[u]+1) {
 78         if(!vis[i]) {
 79             vis[i] = 1;
 80             if(linker[i] == -1 || dfs(linker[i])) {
 81                 linker[i] = u;
 82                 ok[u] = i;
 83                 return 1;
 84             }
 85         }
 86     }
 87     return 0;
 88 }
 89 
 90 int main() {
 91     // FRead();
 92     int T;
 93     Rint(T);
 94     W(T) {
 95         Rint(n);
 96         Cls(ok); Clr(linker, -1); Cls(vis); ret = 0;
 97         For(i, 1, n+1) {
 98             Rint(x[i]); Rint(y[i]);
 99         }
100         for(int i = n; i >= 1; i--) {
101             Cls(vis);
102             if(dfs(i)) ret++;
103         }
104         printf("%d
", ret);
105         vi fuck;
106         For(i, 1, n+1) {
107             if(ok[i]) fuck.pb(i);
108         }
109         printf("%d", fuck[0]);
110         For(i, 1, fuck.size()) printf(" %d", fuck[i]);
111         printf("
");
112     }
113     RT 0;
114 }
I
原文地址:https://www.cnblogs.com/kirai/p/5800213.html