Problem 1001
考虑到直接搜肯定TLE。
我们从起点开始搜10步,再从终点开始搜10步。
其中,从终点开始搜10步通过预处理完成,因为每一次的终点都是一样的。
存状态的时候我把0变成6(为了调试方便),把所有数字写在一行。
然后把这个大数看成一个7进制数,刚好在long long的范围内。
状态用map存储即可。
(幸好比赛的时候做出了这题……)
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = (1 << 23) + 60; const int Q = 63; const LL w[Q] = {0, 6, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5}; LL bit[Q], pre; int p[Q][Q], a[Q], T, pos, ans, cnt = 0; vector <int> v[Q]; map <LL, int> MP, mp; void dfs(int x, int z, LL now){ if (!mp[now]) mp[now] = x; else mp[now] = min(mp[now], x); if (x > 10) return; for (auto u : v[z]){ LL ooo = 21 - z; LL ol = now / bit[ooo]; LL lo = ol % 7; LL eee = 21 - u; LL el = now / bit[eee]; LL le = el % 7; LL fff = now - lo * bit[ooo] - le * bit[eee] + lo * bit[eee] + le * bit[ooo]; dfs(x + 1, u, fff); } } void pre_dfs(int x, int z, LL now){ if (!MP[now]) MP[now] = x; else MP[now] = min(MP[now], x); if (x > 10) return; for (auto u : v[z]){ LL ooo = 21 - z; LL ol = now / bit[ooo]; LL lo = ol % 7; LL eee = 21 - u; LL el = now / bit[eee]; LL le = el % 7; LL fff = now - lo * bit[ooo] - le * bit[eee] + lo * bit[eee] + le * bit[ooo]; pre_dfs(x + 1, u, fff); } } int main(){ bit[0] = 1; rep(i, 1, 21) bit[i] = bit[i - 1] * 7LL; rep(i, 1, 6){ rep(j, 1, i){ ++cnt; p[i][j] = cnt; } } rep(i, 1, 6){ rep(j, 1, i){ int nx = i - 1, ny = j - 1; if (nx > 0 && ny > 0 && p[nx][ny]){ v[p[i][j]].push_back(p[nx][ny]); } nx = i - 1, ny = j; if (nx > 0 && ny > 0 && p[nx][ny]){ v[p[i][j]].push_back(p[nx][ny]); } nx = i + 1, ny = j; if (nx > 0 && ny > 0 && p[nx][ny]){ v[p[i][j]].push_back(p[nx][ny]); } nx = i + 1, ny = j + 1; if (nx > 0 && ny > 0 && p[nx][ny]){ v[p[i][j]].push_back(p[nx][ny]); } } } LL pre = 0; rep(i, 1, 21) pre = pre * 7LL + w[i]; pre_dfs(1, 1, pre); scanf("%d", &T); while (T--){ mp.clear(); pos = 0; rep(i, 1, 21){ scanf("%d", a + i); if (a[i] == 0){ pos = i; a[i] = 6; } } LL st = 0; rep(i, 1, 21) st = st * 7LL + a[i]; dfs(1, pos, st); ans = 1 << 30; bool fl = false; for (auto pppp : MP){ LL ooo = pppp.first; if (mp[ooo] > 0){ ans = min(ans, mp[ooo] - 1 + pppp.second - 1); fl = true; } } if (fl) printf("%d ", ans); else puts("too difficult"); } return 0; }
Problem 1002
比赛时并未想到,觉得这是一个近似的等比数列
然后一直在找公比是多少,然而并未找到
赛后才发现,最后要求的数列也存在递推关系
(可以用数学方法解出)
只要找出相应的系数即可
然后用矩阵快速幂进行计算
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cstring> 7 #include<string> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #include<queue> 12 using namespace std; 13 typedef long long ll; 14 const ll mod=1e9+7; 15 int _; 16 struct matrix 17 { 18 ll a[2][2]; 19 matrix() 20 { 21 a[0][0]=a[1][1]=1; 22 a[0][1]=a[1][0]=0; 23 } 24 matrix operator *(const matrix &b) const 25 { 26 matrix ret; 27 ret.a[0][0] = ( a[0][0] * b.a[0][0] %mod+ a[0][1] * b.a[1][0] %mod) % mod; 28 ret.a[0][1] = ( a[0][0] * b.a[0][1] %mod+ a[0][1] * b.a[1][1] %mod) % mod; 29 ret.a[1][0] = ( a[1][0] * b.a[0][0] %mod+ a[1][1] * b.a[1][0] %mod) % mod; 30 ret.a[1][1] = ( a[1][0] * b.a[0][1] %mod+ a[1][1] * b.a[1][1] %mod) % mod; 31 return ret; 32 } 33 } C; 34 matrix pow_mod(matrix a,ll b) 35 { 36 matrix ans; 37 while (b) 38 { 39 if (b&1) ans=ans*a; 40 b>>=1; 41 a=a*a; 42 } 43 return ans; 44 } 45 ll get(ll n) 46 { 47 if (n==0) return 0; 48 if (n==1) return 1; 49 return pow_mod(C,n-1).a[0][0]; 50 } 51 int main() 52 { 53 C.a[0][0]=7; 54 C.a[0][1]=-4; 55 C.a[1][0]=1; 56 C.a[1][1]=0; 57 scanf("%d",&_); 58 while (_--) 59 { 60 ll n; 61 scanf("%lld",&n); 62 printf("%lld ",(get(n+1)-2*get(n)+mod*6)%mod); 63 } 64 }
Problem 1008
事实上,这是个最小点覆盖问题
设树上最大匹配数*2为tmp
如果k <tmp,那么答案为(k+1)/2
否则,答案为tmp/2+(k-tmp)
由于读入量大,还需要加人读入挂
1 #include <bits/stdc++.h> 2 3 namespace IO{ 4 const int MT = 50 * 1024 * 1024; 5 char IO_BUF[MT]; 6 int IO_PTR, IO_SZ; 7 8 void begin(){ 9 IO_PTR = 0; 10 IO_SZ = fread (IO_BUF, 1, MT, stdin); 11 } 12 template<typename T> 13 inline bool scan_d (T & t){ 14 while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != '-' && (IO_BUF[IO_PTR] < '0' || IO_BUF[IO_PTR] > '9'))IO_PTR ++; 15 if (IO_PTR >= IO_SZ) return false; 16 bool sgn = false; 17 if (IO_BUF[IO_PTR] == '-') sgn = true, IO_PTR ++; 18 for (t = 0; IO_PTR < IO_SZ && '0' <= IO_BUF[IO_PTR] && IO_BUF[IO_PTR] <= '9'; IO_PTR ++) 19 t = t * 10 + IO_BUF[IO_PTR] - '0'; 20 if (sgn) t = -t; 21 return true; 22 23 } 24 inline bool scan_s (char s[]){ 25 while (IO_PTR < IO_SZ && (IO_BUF[IO_PTR] == ' ' || IO_BUF[IO_PTR] == ' ') ) IO_PTR ++; 26 if (IO_PTR >= IO_SZ) return false; 27 int len = 0; 28 while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != ' ' && IO_BUF[IO_PTR] != ' ') 29 s[len++] = IO_BUF[IO_PTR], IO_PTR ++; 30 s[len] = '