XVII Open Cup named after E.V. Pankratiev. XXI Ural Championship
A. Apple
按题意模拟即可。
- #include<stdio.h>
- #include<iostream>
- #include<string.h>
- #include<string>
- #include<ctype.h>
- #include<math.h>
- #include<set>
- #include<map>
- #include<vector>
- #include<queue>
- #include<bitset>
- #include<algorithm>
- #include<time.h>
- using namespace std;
- void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
- #define MS(x, y) memset(x, y, sizeof(x))
- #define ls o<<1
- #define rs o<<1|1
- typedef long long LL;
- typedef unsigned long long UL;
- typedef unsigned int UI;
- template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
- template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
- const int N = 105, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
- template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
- int casenum, casei;
- int n, m;
- vector<int>a[N];
- int ind1 = 0, ind1num = 0;
- int ind2num = 0;
- int ind3 = 0, ind3num = 0;
- bool vis[N];
- int ind[N];
- int cnt;
- bool dfs1(int x, int fa)
- {
- ++cnt;
- vis[x] = 1;
- for(auto y : a[x])if(y != fa)
- {
- if(!vis[y])
- {
- if(!dfs1(y, x))return 0;
- }
- else if(y != ind3)return 0;
- }
- return 1;
- }
- void dfs3(int x, int fa)
- {
- ++cnt;
- vis[x] = 1;
- for(auto y : a[x])if(y != fa)
- {
- if(!vis[y])
- {
- dfs3(y, x);
- }
- }
- }
- bool solve()
- {
- if(ind1num != 1)return 0;
- if(ind2num != n - 2)return 0;
- if(ind3num != 1)return 0;
- cnt = 0;
- vis[ind3] = true;
- if(!dfs1(ind1, 0))return 0;
- dfs3(ind3, 0);
- if(cnt != n)return 0;
- return 1;
- }
- int main()
- {
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- while(~scanf("%d%d", &n, &m))
- {
- for(int i = 1; i <= n; ++i)
- {
- a[i].clear();
- ind[i] = 0;
- vis[i] = 0;
- }
- for(int i = 1; i <= m; ++i)
- {
- int x, y; scanf("%d%d", &x, &y);
- a[x].push_back(y);
- a[y].push_back(x);
- ++ind[x];
- ++ind[y];
- }
- ind1 = 0, ind1num = 0;
- ind2num = 0;
- ind3 = 0, ind3num = 0;
- for(int i = 1; i <= n; ++i)
- {
- if(ind[i] == 1)
- {
- ++ind1num;
- ind1 = i;
- }
- else if(ind[i] == 2)
- {
- ++ind2num;
- }
- else if(ind[i] == 3)
- {
- ++ind3num;
- ind3 = i;
- }
- }
- puts(solve() ? "Yes" : "No");
- }
- return 0;
- }
- /*
- 【trick&&吐槽】
- 【题意】
- 【分析】
- 【时间复杂度&&优化】
- 9 9
- 1 2
- 2 3
- 3 5
- 5 6
- 6 4
- 4 7
- 1 7
- 7 9
- 8 9
- 5 5
- 1 2
- 2 3
- 1 3
- 1 4
- 1 5
- 4 4
- 1 2
- 2 3
- 1 3
- 1 4
- 5 4
- 1 2
- 2 3
- 1 3
- 1 4
- */
B. Bar charts
关于序列的前缀和建立差分约束系统,SPFA判断是否存在负环。
- #include<cstdio>
- #include<cstdlib>
- using namespace std;
- const int N=12222,M=1000000,E=10000000,inf=~0U>>1;
- int n,i,g[N],v[M],w[M],nxt[M],ed,d[N];
- int x,h,t,q[E];
- int vis[N],in[N];
- inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
- inline void make(int x,int y,int z){
- //x-y=z
- add(y,x,z);
- add(x,y,-z);
- }
- void gao(){
- int k,b,s;
- scanf("%d%d%d",&k,&b,&s);
- make(b-1,0,0);
- for(int i=b+k*s;i<=n;i++)make(i,i-1,0);
- for(int i=1;i<=k;i++){
- int l=b+(i-1)*s,r=b+i*s;
- int o;
- scanf("%d",&o);
- //s[r-1]-s[l-1]
- make(r-1,l-1,o);
- }
- }
- void NO(){
- puts("No");
- exit(0);
- }
- inline void ext(int x,int y){
- if(y<0)NO();
- if(y>=d[x])return;
- d[x]=y;
- if(!in[x]){
- in[x]=1;
- vis[x]++;
- if(vis[x]>=n)NO();
- q[++t]=x;
- if(t>=E-10)NO();
- }
- }
- int main(){
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- n=11111;
- for(i=0;i<n;i++)add(i+1,i,0);
- gao();
- gao();
- for(i=0;i<=n;i++){
- d[i]=inf;
- }
- h=1,t=0;
- ext(0,0);
- while(h<=t){
- x=q[h++];
- for(i=g[x];i;i=nxt[i])ext(v[i],d[x]+w[i]);
- in[x]=0;
- }
- puts("Yes");
- }
C. Construction sets
二分答案,二进制拆分背包+bitset检验。
- #include<stdio.h>
- #include<iostream>
- #include<string.h>
- #include<string>
- #include<ctype.h>
- #include<math.h>
- #include<set>
- #include<map>
- #include<vector>
- #include<queue>
- #include<bitset>
- #include<algorithm>
- #include<time.h>
- using namespace std;
- void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
- #define MS(x, y) memset(x, y, sizeof(x))
- #define ls o<<1
- #define rs o<<1|1
- typedef long long LL;
- typedef unsigned long long UL;
- typedef unsigned int UI;
- template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
- template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
- const int N = 55, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
- template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
- int casenum, casei;
- int n, mn, mx;
- int m[N], c[N];
- bitset<10005>f;
- bool check(int K)
- {
- f.reset(); f[0] = 1;
- for(int i = 1; i <= n; ++i)
- {
- int tot = c[i] / K;
- int g = 1;
- LL v = m[i];
- while(tot)
- {
- if(v > mx)break;
- f |= f << v;
- tot -= g;
- g = min(g * 2, tot);
- v = (LL)m[i] * g;
- }
- }
- for(int j = mn; j <= mx; ++j)
- {
- if(f[j])return 1;
- }
- return 0;
- }
- int main()
- {
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- while(~scanf("%d%d%d", &n, &mn, &mx))
- {
- for(int i = 1; i <= n; ++i)
- {
- scanf("%d%d", &m[i], &c[i]);
- }
- int l = 0;
- int r = 1e6;
- while(l < r)
- {
- int mid = (l + r + 1) >> 1;
- if(check(mid))
- {
- l = mid;
- }
- else
- {
- r = mid - 1;
- }
- }
- printf("%d\n", l);
- }
- return 0;
- }
- /*
- 【trick&&吐槽】
- 【题意】
- 【分析】
- 【时间复杂度&&优化】
- 3 12 13
- 3 8
- 4 6
- 7 9
- */
D. Dinner party
$f[i][j]$表示面积和为$i$的矩形,周长和为$j$是否有可能,bitset加速。
- #include<cstdio>
- #include<bitset>
- using namespace std;
- const int N=1010,M=2010;
- int T,n,m,i,j,x,y,cnt;
- bitset<M>f[N];
- void solve(){
- scanf("%d%d",&n,&m);
- if(m%2){
- puts("No");
- return;
- }
- m/=2;
- if(f[n][m]==0){
- puts("No");
- return;
- }
- puts("Yes");
- int cnt=0;
- static int q[100000][2];
- while(n){
- int X=0,Y=0;
- for(x=1;x<=n;x++){
- for(y=1;y*x<=n;y++)if(x+y<=m)if(f[n-x*y][m-x-y]){
- X=x,Y=y;
- break;
- }
- if(X)break;
- }
- q[++cnt][0]=X;
- q[cnt][1]=Y;
- n-=X*Y;
- m-=X+Y;
- }
- printf("%d\n",cnt);
- for(int i=1;i<=cnt;i++)printf("%d %d\n",q[i][0],q[i][1]);
- }
- int main(){
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- //scanf("%d%d",&n,&m);
- n=1000;
- m=2000;
- f[0][0]=1;
- for(i=0;i<=n;i++)
- for(x=1;x+i<=n;x++)
- for(y=1;x*y+i<=n;y++)
- f[i+x*y]|=f[i]<<(x+y);
- scanf("%d",&T);
- while(T--)solve();
- }
E. Expression on dice
若要构造$=$,则在两侧构造$0$即可,否则随意构造。
- //
- // main.cpp
- // opencup 10378 E
- //
- // Created by luras on 2017/9/14.
- // Copyright © 2017年 luras. All rights reserved.
- //
- #define ms(x, y) memset(x, y, sizeof(x))
- #define mc(x, y) memcpy(x, y, sizeof(x))
- #define lson o << 1, l, mid
- #define rson o << 1 | 1, mid + 1, r
- #define ls o << 1
- #define rs o << 1 | 1
- #include<stdio.h>
- #include<string.h>
- #include<math.h>
- #include<queue>
- #include<map>
- #include<stack>
- #include<time.h>
- #include<vector>
- #include<list>
- #include<set>
- #include<iostream>
- #include<stdlib.h>
- #include<string>
- #include<algorithm>
- #pragma comment(linker,"/STACK:102400000,102400000")
- template <class T> inline void gmax(T &a, T b){if(b > a) a = b;}
- template <class T> inline void gmin(T &a, T b){if(b < a) a = b;}
- using namespace std;
- const int N = 1e6 + 10, M = 2e6 + 10, Z = 1e9 + 7, maxint = 2147483647, ms1 = 16843009, ms31 = 522133279, ms63 = 1061109567, ms127 = 2139062143;
- const double PI = acos(-1.0), eps = 1e-8;
- typedef long long LL;
- void fre()
- {
- freopen("/Users/luras/Desktop/in.txt", "r", stdin);
- freopen("/Users/luras/Desktop/out.txt", "w", stdout);
- }
- const int INF = 1e9;
- int casenum, casei;
- int priv[N];
- double calc(double a, double b, char op)
- {
- if(op == '+') return a + b;
- if(op == '-') return a - b;
- if(op == '*') return a * b;
- if(op == '/') return a / b;
- return 0;
- }
- double calculate(string str)
- {
- stack<double> num;
- stack<char> oper;
- priv['+'] = priv['-'] = 3;
- priv['*'] = priv['/'] = 2;
- priv['('] = 10;
- double x, y, t = 0;
- int i; char last = 0;
- for(i = 0; i < str.length(); i ++){
- if(isdigit(str[i])){
- num.push(atof(str.c_str() + i));
- for(; i + 1 < str.length() && isdigit(str[i + 1]); i ++);
- if(i + 1 < str.length() && str[i + 1] == '.')
- for(i ++; i + 1 < str.length() && isdigit(str[i + 1]); i ++);
- }
- else if(str[i] == '('){
- oper.push(str[i]);
- }
- else if(str[i] == ')'){
- while(oper.top() != '('){
- y = num.top(); num.pop();
- x = num.top(); num.pop();
- char op = oper.top();
- oper.pop();
- num.push(calc(x, y, op));
- }
- oper.pop();
- }
- else if(str[i] == '-' && (last == 0 || last == '(')){
- num.push(0.0);
- oper.push('-');
- }
- else if(priv[str[i]] > 0){
- while(oper.size() > 0 && priv[str[i]] >= priv[oper.top()]){
- y = num.top(); num.pop();
- x = num.top(); num.pop();
- char op = oper.top();
- oper.pop();
- num.push(calc(x, y, op));
- }
- oper.push(str[i]);
- }else continue;
- last = str[i];
- }
- while(oper.size() > 0){
- y = num.top(); num.pop();
- x = num.top(); num.pop();
- char op = oper.top();
- oper.pop();
- num.push(calc(x, y, op));
- }
- return num.top();
- }
- map<int, bool> mop;
- vector<int> num;
- vector<char> sym;
- int lft, rgt, zero, divi, typ;
- const string sta[6][6] ={
- {"=", "<", ">", "!=", "<=", ">="},
- {"4", "+", "-", "(", "(", ")"},
- {"0", "/", "/", "/", "8", "+"},
- {"2", "3", "4", "5", "-", ")"},
- {"+", "-", "*", "/", "1", "9"},
- {"6", "7", "+", "-", "(", ")"}
- };
- void ask(int o)
- {
- char ch;
- if(o == 2){
- puts("2");
- fflush(stdout);
- scanf(" %c", &ch);
- //ch = sta[1][rand() % 6][0];
- //cout << "A: " << ch;
- if(ch == '(') lft ++;
- else if(ch == ')') rgt ++;
- else if(ch == '4') {
- num.push_back(ch);
- if(mop[ch] == 0){
- mop[ch] = 1;
- typ ++;
- }
- }
- else sym.push_back(ch);
- }
- else if(o == 3){
- puts("3");
- fflush(stdout);
- scanf(" %c", &ch);
- //ch = sta[2][rand() % 6][0];
- //cout << "A: " << ch;
- if(ch == '0') zero ++;
- else if(ch == '8') {
- num.push_back(ch);
- if(mop[ch] == 0){
- mop[ch] = 1;
- typ ++;
- }
- }
- else if(ch == '/') divi ++;
- else sym.push_back(ch);
- }
- else if(o == 4){
- puts("4");
- fflush(stdout);
- //ch = sta[3][rand() % 6][0];
- //cout << "A: " << ch;
- scanf(" %c", &ch);
- if(ch == '-') sym.push_back(ch);
- else if(ch == ')') rgt ++;
- else {
- num.push_back(ch);
- if(mop[ch] == 0){
- mop[ch] = 1;
- typ ++;
- }
- }
- }
- }
- string ans;
- string s;
- string ss;
- int sgn(double x)
- {
- if(fabs(x) < eps) return 0;
- return x > 0 ? 1 : -1;
- }
- bool choose()
- {
- s = "";
- int DIV = divi, ZERO = zero;
- int n = num.size(), m = sym.size() + DIV;
- int bas = (n + ZERO) / (m + 1);
- int mo = (n + ZERO) - (m + 1) * bas;
- int t = 0, j = -1, k = -1;
- for(int i = 0; i < m + 1; i ++){
- if(mo){
- if(j + 1 >= n) return 0; // 必须得放前导0了
- s += num[++ j]; ++ t;
- while(t <= bas && ZERO){
- s += '0'; t ++; ZERO --;
- }
- while(t <= bas){
- s += num[++ j]; t ++;
- }
- mo --;
- t = 0;
- }
- else{
- if(j + 1 >= n) return 0;
- s += num[++ j]; ++ t;
- while(t < bas && ZERO){
- s += '0'; t ++; ZERO --;
- }
- while(t < bas){
- s += num[++ j]; t ++;
- }
- t = 0;
- }
- if(DIV){
- s += '/';
- DIV --;
- }
- else{
- if(k + 1 < sym.size())s += sym[++ k];
- }
- }
- return 1;
- }
- bool check(int o)
- {
- if(o == 0){
- zero -= 2; lft --; rgt --; divi --;
- if(!choose()) {zero += 2; lft ++; rgt ++; divi ++; return 0;}
- if(calculate(s) != 0){
- ans = "";
- for(int i = 0; i < lft; i ++) ans += '(';
- ans += '0';
- for(int i = 0; i < rgt; i ++) ans += ')';
- ans += "=0/(" + s + ')';
- }
- else {zero += 2; lft ++; rgt ++; divi ++; return 0;}
- }
- else{
- zero --;
- if(!choose()) {zero ++;return 0;}
- double tmp = calculate(s);
- if(sgn(tmp) != 0){
- if(ss[0] == '<' && sgn(tmp) > 0 || ss[0] == '>' && sgn(tmp) < 0){
- ans = "";
- for(int i = 0; i < lft; i ++) ans += '(';
- ans += '0';
- for(int i = 0; i < lft; i ++) ans += ')';
- ans += ss + s;
- }
- else{
- ans = "";
- for(int i = 0; i < lft; i ++) ans += '(';
- ans += s;
- for(int i = 0; i < lft; i ++) ans += ')';
- ans += ss + '0';
- }
- }
- else if(ss == "!="){
- ans = "";
- for(int i = 0; i < lft; i ++) ans += '(';
- ans += '0';
- for(int i = 0; i < lft; i ++) ans += ')';
- ans += ss + s;
- }
- else {zero ++; return 0;}
- }
- return 1;
- }
- int main()
- {
- srand(time(NULL));
- //fre();
- puts("1");
- fflush(stdout);
- cin >> ss;
- //ss = sta[0][rand() % 6];
- //cout << ss << endl;
- lft = rgt = zero = divi = typ = 0;
- int tim = 0;
- while(1){
- if(++ tim == 1000){
- int go = 1;
- }
- if(zero < (ss[0] == '=' ? 2 : 1) || divi == 0){
- ask(3);
- }
- else if(lft < rgt || lft == 0){
- ask(2);
- }
- else if(num.size() - 2 < sym.size() || rgt < lft){
- ask(4);
- }
- else {
- if(check(ss[0] == '=' ? 0 : 1)) break;
- ask(4);
- }
- }
- printf("0 ");
- cout << ans << endl;
- fflush(stdout);
- return 0;
- }
- /*
- 题意:
- 类型:
- 分析:
- 优化:
- trick:
- 数据:
- Sample Input
- Sample Output
- >=
- + / / + 8 0 ) ( ) ( - - 5 5 5 - 4 4 4 - 5 3
- */
F. Flight trip
留坑。
G. Glasses with solutions
找出的子集需要满足$b\sum m-a\sum t=0$,折半搜索即可。
- #include<cstdio>
- #include<map>
- using namespace std;
- typedef long long ll;
- const int N=40;
- int n,m,A,B,i,x,y,a[N];map<ll,ll>f;
- ll ans;
- void dfsl(int x,ll y){
- if(x==m){f[y]++;return;}
- dfsl(x+1,y+a[x]);
- dfsl(x+1,y);
- }
- void dfsr(int x,ll y){
- if(x==n){ans+=f[-y];return;}
- dfsr(x+1,y+a[x]);
- dfsr(x+1,y);
- }
- int main(){
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- scanf("%d%d%d",&n,&A,&B);
- for(i=0;i<n;i++){
- scanf("%d%d",&x,&y);
- a[i]=x*B-A*y;
- }
- m=n/2;
- dfsl(0,0);
- dfsr(m,0);
- ans--;
- printf("%lld",ans);
- }
H. Hamburgers
对于每个汉堡,$O(2^6)$枚举所有它可以满足的口味,然后对于每个人判断是否满足即可。
时间复杂度$O(m\sum a+2^6\sum b)$。
- #include<cstdio>
- #include<cstring>
- #include<vector>
- using namespace std;
- const int N=55555;
- int n,m,i,j,k,x,ans[N],mx[N],b[N];
- vector<int>a[N];
- bool v[(1<<26)+5];
- inline int get(){
- static char s[1000];
- scanf("%s",s);
- int t=0,len=strlen(s);
- for(int i=0;i<len;i++)t|=1<<(s[i]-'a');
- return t;
- }
- inline void make(int x,int y){
- for(int i=x;i;i=(i-1)&x)v[i]=y;
- }
- int main(){
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- scanf("%d",&n);
- for(i=1;i<=n;i++){
- scanf("%d",&k);
- while(k--){
- x=get();
- a[i].push_back(x);
- }
- ans[i]=1;
- }
- scanf("%d",&m);
- for(i=1;i<=m;i++){
- scanf("%d",&k);
- for(j=1;j<=k;j++)b[j]=get();
- for(j=1;j<=k;j++)make(b[j],1);
- for(j=1;j<=n;j++){
- int t=0;
- for(x=0;x<a[j].size();x++)if(v[a[j][x]])t++;
- if(t>mx[j])mx[j]=t,ans[j]=i;
- }
- for(j=1;j<=k;j++)make(b[j],0);
- }
- for(i=1;i<=n;i++)printf("%d\n",ans[i]);
- }
- /*
- 5
- 1
- a
- 3
- a
- ba
- cb
- 3
- vba
- d
- ba
- 3
- ca
- da
- da
- 3
- as
- ba
- af
- 2
- 4
- abc
- abcd
- a
- a
- 2
- abcdef
- abcdev
- */
I. Intricate path
留坑。
J. Jumps through the Hyperspace
显然到每个点的时间越早越好,对于每种传送门预处理出每种余数下的最优等待时间即可。
- #include<cstdio>
- #include<algorithm>
- #include<vector>
- #include<queue>
- using namespace std;
- typedef pair<int,int>P;
- const int N=2010,inf=~0U>>1;
- int n,m,st,i,j,a[N],b[N],c[N],d[N],w[N][N];
- int f[N];
- char g[N][N],op[N];
- priority_queue<P,vector<P>,greater<P> >q;
- inline void ext(int x,int y){
- if(f[x]>y)q.push(P(f[x]=y,x));
- }
- int main(){
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- scanf("%d%d%d",&n,&m,&st);
- while(m--){
- scanf("%s",op);
- int o=op[0];
- scanf("%d%d%d%d",&a[o],&b[o],&c[o],&d[o]);
- for(i=0;i<c[o];i++){
- w[o][i]=inf;
- for(j=0;j<c[o];j++)w[o][i]=min(w[o][i],(a[o]*(i+j)+b[o])%c[o]+d[o]+j);
- }
- }
- for(i=1;i<=n;i++)scanf("%s",g[i]+1);
- for(i=1;i<=n;i++)f[i]=inf;
- ext(1,st);
- while(!q.empty()){
- P t=q.top();q.pop();
- if(f[t.second]<t.first)continue;
- for(i=1;i<=n;i++)if(g[t.second][i]!='.')
- ext(i,t.first+w[g[t.second][i]][t.first%c[g[t.second][i]]]);
- }
- if(f[n]==inf)puts("-1");else
- printf("%d",f[n]-st);
- }
K. King’s island
暴力搜索出一个上凸壳,然后翻转拼接起来得到完整的多边形即可。
- #include<stdio.h>
- #include<iostream>
- #include<string.h>
- #include<string>
- #include<ctype.h>
- #include<math.h>
- #include<set>
- #include<map>
- #include<vector>
- #include<queue>
- #include<bitset>
- #include<algorithm>
- #include<time.h>
- using namespace std;
- void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
- #define MS(x, y) memset(x, y, sizeof(x))
- #define ls o<<1
- #define rs o<<1|1
- typedef long long LL;
- typedef unsigned long long UL;
- typedef unsigned int UI;
- template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
- template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
- const int N = 1010, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
- template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
- int casenum, casei;
- int n;
- struct B
- {
- int x, y;
- bool operator < (const B & b)const
- {
- //y/x > b.y/b.x
- return y * b.x > x * b.y;
- }
- };
- B p[100000]; int g;
- int f[N][N][62];
- struct A
- {
- int x, y, z;
- };
- bool bingo[60];
- vector<B>ans[60];
- void getvt(int x, int y, int v, vector<B>&vt, int DX, int DY)
- {
- if(v == 0)return;
- int o = f[x][y][v];
- if(f[x - p[o].x][y - p[o].y][v] == o)
- {
- getvt(x - p[o].x, y - p[o].y, v, vt, DX + p[o].x, DY + p[o].y);
- }
- else
- {
- vt.push_back({p[o].x + DX, p[o].y + DY});
- getvt(x - p[o].x, y - p[o].y, v - 1, vt, 0, 0);
- }
- }
- void init()
- {
- for(int i = 1; i <= 200; ++i)
- {
- for(int j = i + 1; j <= 200; ++j)if(__gcd(i, j) == 1)
- {
- int W = (i * i + j * j);
- int w = sqrt(W);
- if(w * w == W)
- {
- p[++g] = {i, j};
- p[++g] = {j, i};
- }
- }
- }
- sort(p + 1, p + g + 1);
- //printf("%d\n", g);
- MS(f, 0);
- f[0][0][0] = 1;
- for(int i = 0; i <= 500; ++i)
- {
- for(int j = 0; j <= 500; ++j)
- {
- for(int v = 29; v >= 0; --v)if(f[i][j][v])
- {
- //
- int k = f[i][j][v];
- auto &it = f[i + p[k].x][j + p[k].y][v];
- if(it == 0)it = k;
- //
- for(int k = f[i][j][v] + 1; k <= g; ++k)
- {
- auto &it = f[i + p[k].x][j + p[k].y][v + 1];
- if(it == 0)it = k;
- }
- if(i == 0 || j == 0)continue;
- for(int u = 1; u + v <= 30; ++u)if(f[i][j][u] && f[i][j][u] != f[i][j][v])
- {
- if(!bingo[u + v])
- {
- bingo[u + v] = 1;
- vector<B>up, down;
- getvt(i, j, u, up, 0, 0);
- getvt(i, j, v, down, 0, 0);
- int x = i;
- int y = j;
- //printf("%d %d %d\n", u + v, up.size(), down.size());
- //puts("up------------");
- for(int r = 0; r < up.size(); ++r)
- {
- x -= up[r].x;
- y -= up[r].y;
- ans[u + v].push_back({x, y});
- //printf("%d %d\n", up[r].x, up[r].y);
- }
- //puts("down------------");
- for(int r = 0; r < down.size(); ++r)
- {
- x += down[r].x;
- y += down[r].y;
- ans[u + v].push_back({x, y});
- //printf("%d %d\n", down[r].x, down[r].y);
- }
- //puts("ans------");
- for(auto w : ans[u + v])
- {
- //printf("%d %d\n", w.x, w.y);
- }
- int pasue = 1;
- }
- }
- }
- }
- }
- for(int i = 1;i <= 30; ++i)
- {
- //printf("%d\n", bingo[i]);
- }
- }
- int main()
- {
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- init();
- while(~scanf("%d", &n))
- {
- if(n == 3)
- {
- puts("0 0\n4 3\n-20 21");
- continue;
- }
- for(auto it : ans[n])
- {
- printf("%d %d\n", it.x, it.y);
- }
- }
- return 0;
- }
- /*
- 【trick&&吐槽】
- 【题意】
- 【分析】
- 【时间复杂度&&优化】
- 28 195
- 9 15
- -116 178
- 4
- 20 21
- 1 -159
- -236 -11
- -92 6
- 5
- 20 50
- 3 -94
- -16 -274
- -236 18
- -92 35
- */
L. Lexica
无视同一行/同一列的两个格子的位置关系,只需要在它们不相同时将方案数乘$2$,如此一来只关心每一行/每一列有多少格子没满足。
设$f[i][j][S][k]$表示考虑到$(i,j)$,每一列剩余情况为$S$,第$i$行还有$k$个格子需要填充时的方案数,然后逐格转移即可。
时间复杂度$O(n3^n)$。
- #include<cstdio>
- typedef unsigned long long ll;
- const int N=18,M=1600000;
- int n,m,all,i,j,k,x,y,z,A,B,C,S,o,p[N],mask,cnt[N];
- char a[N][N];
- int e;
- ll f[2][M][3],mul;
- int w[M];
- inline void clr(){
- for(int i=0;i<=mask;i++)for(int j=0;j<3;j++)f[e^1][i][j]=0;
- }
- inline void nxt(){
- //for(int i=0;i<=mask;i++)for(int j=0;j<3;j++)f[i][j]=g[i][j];
- }
- inline int get(int S,int x){
- return S/p[x]%3;
- }
- void dfs(int x,int y,int z){
- if(x==n){
- w[y]=z;
- return;
- }
- for(int i=0;i<3;i++)dfs(x+1,y*3+i,z*2+(!!i));
- }
- int main(){
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- scanf("%d",&n);
- m=n+2;
- for(i=0;i<m;i++)scanf("%s",a[i]);
- mul=1;
- for(p[0]=i=1;i<N;i++)p[i]=p[i-1]*3;
- all=p[n];
- for(i=1;i<=n;i++){
- if(a[0][i]!='#'&&a[m-1][i]!='#'&&a[0][i]!=a[m-1][i])mul*=2;
- if(a[i][0]!='#'&&a[i][m-1]!='#'&&a[i][0]!=a[i][m-1])mul*=2;
- if(a[i][0]!='#')cnt[i]++;
- if(a[i][m-1]!='#')cnt[i]++;
- if(a[0][i]!='#')mask+=p[i-1];
- if(a[m-1][i]!='#')mask+=p[i-1];
- }
- dfs(0,0,0);
- f[0][mask][0]=mul;
- for(i=1;i<=n;i++){
- clr();
- int o=cnt[i];
- for(A=0;A<=mask;A++)f[e^1][A][o]=f[e][A][0];
- e^=1;
- for(j=0;j<n;j++)if(a[i][j+1]=='.'){
- clr();
- for(S=0;S<=mask;S++){
- if(w[S]>>j&1)for(k=0;k<=o;k++)if(f[e][S][k])f[e^1][S-p[j]][k]+=f[e][S][k];
- for(k=1;k<=o;k++)if(f[e][S][k])f[e^1][S][k-1]+=f[e][S][k];
- }
- e^=1;
- }
- }
- printf("%llu",f[e][0][0]);
- }
- /*
- 5
- ##ARRR#
- H.#.##S
- Y.....E
- O.#.#.E
- ##....E
- ###.#.E
- #XNT#A#
- */
M. Maximal paths
树形DP求出每个点内部从叶子往上、从上往下的最大数字串即可。需要手写高精度。
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- typedef unsigned long long ll;
- typedef __int128 lll;
- const int N=10000010,M=50;
- const ll MO=1000000000000000000ULL;
- int n,i;char a[N];
- struct P{
- ll v[3];
- P(){v[0]=v[1]=v[2]=0;}
- P operator+(int b){
- P c;
- for(int i=0;i<3;i++)c.v[i]=v[i];
- c.v[0]+=b;
- for(int i=0;i<2;i++)if(c.v[i]>=MO){
- c.v[i+1]+=c.v[i]/MO;
- c.v[i]-=MO;
- }
- return c;
- }
- P operator+(const P&b){
- P c;
- for(int i=0;i<3;i++)c.v[i]=v[i]+b.v[i];
- for(int i=0;i<2;i++)if(c.v[i]>=MO){
- c.v[i+1]+=c.v[i]/MO;
- c.v[i]-=MO;
- }
- return c;
- }
- P operator*(int b){
- P c;
- for(int i=0;i<3;i++)c.v[i]=v[i]*b;
- for(int i=0;i<2;i++)c.v[i+1]+=c.v[i]/MO,c.v[i]%=MO;
- c.v[2]%=MO;
- return c;
- }
- P operator*(const P&b){
- P c;
- static lll f[3];
- f[0]=f[1]=f[2]=0;
- for(int i=0;i<3;i++)if(v[i])for(int j=0;i+j<3;j++)if(b.v[j])f[i+j]+=(lll)v[i]*b.v[j];
- for(int i=0;i<2;i++)if(f[i]>=MO)f[i+1]+=f[i]/MO,f[i]%=MO;
- if(f[2]>=MO)f[2]%=MO;
- for(int i=0;i<3;i++)c.v[i]=f[i];
- return c;
- }
- void up(const P&b){//max=
- int i;
- for(i=2;~i;i--)if(b.v[i]!=v[i])break;
- if(i<0)return;
- if(b.v[i]<v[i])return;
- for(i=0;i<3;i++)v[i]=b.v[i];
- }
- void write(){
- int i=2;
- while(i&&!v[i])i--;
- printf("%llu",v[i]);
- for(int j=i-1;~j;j--)printf("%018llu",v[j]);
- puts("");
- }
- }f[M],g[M],p[M],ans,ff,gg,mx[M];
- int d[M];
- unsigned int seed,base;
- void dfs(int x,int k){
- f[k]=g[k]=mx[k]=P();
- d[k]=0;
- for(int i=0;i<2;i++){
- int y=x<<1|i;
- if(y>n)continue;
- dfs(y,k+1);
- ff=(f[k+1]*10)+((int)a[y]);
- gg=g[k+1]+(p[d[k+1]]*((int)a[y]));
- mx[k].up((ff*p[d[k]])+g[k]);
- mx[k].up((f[k]*p[d[k+1]+1])+gg);
- /*if(x==1){
- puts("debug");
- ff.write();
- f[k].write();
- }*/
- f[k].up(ff);
- g[k].up(gg);
- d[k]=max(d[k],d[k+1]+1);
- /*if(x==1){
- puts("debug");
- ff.write();
- f[k].write();
- }*/
- }
- /* printf("%d:\n",x);
- f[k].write();
- g[k].write();
- mx[k].write();*/
- ans=ans+mx[k];
- }
- int main(){
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- scanf("%d%u",&n,&seed);
- base=(1U<<31)-1;
- p[0].v[0]=1;
- for(i=1;i<M;i++)p[i]=p[i-1]*10;
- for(i=1;i<=n;i++){
- a[i]=((seed&base)>>16)%9+1;
- seed=seed*1103515245+12345;
- //printf("%d\n",a[i]); i and i/2
- }
- dfs(1,0);
- ans.write();
- }
XVII Open Cup named after E.V. Pankratiev. XXI Ural Championship的更多相关文章
- XVII Open Cup named after E.V. Pankratiev. GP of SPb
A. Array Factory 将下标按前缀和排序,然后双指针,维护最大的右边界即可. #include<cstdio> #include<algorithm> using ...
- XVII Open Cup named after E.V. Pankratiev. GP of Two Capitals
A. Artifact Guarding 选出的守卫需要满足$\max(a+b)\leq \sum a$,从小到大枚举每个值作为$\max(a+b)$,在权值线段树上找到最大的若干个$a$即可. 时间 ...
- XVII Open Cup named after E.V. Pankratiev. GP of Moscow Workshops
A. Centroid Tree 枚举至多两个重心作为根,检查对于每个点是否都满足$2size[x]\leq size[father[x]]$即可. #include<stdio.h> # ...
- XVII Open Cup named after E.V. Pankratiev. Eastern GP, Division 1
A. Count The Ones $ans=b-c+1$. #include <stdio.h> using namespace std ; int a , b , c ; void s ...
- XVII Open Cup named after E.V. Pankratiev. GP of Siberia, Division 1
1. Ski race 枚举枚举倍数判断即可.时间复杂度$O(n\log m)$. #include<cstdio> #include<algorithm> using nam ...
- XVII Open Cup named after E.V. Pankratiev. Grand Prix of America (NAIPC-2017)
A. Pieces of Parentheses 将括号串排序,先处理会使左括号数增加的串,这里面先处理减少的值少的串:再处理会使左括号数减少的串,这里面先处理差值较大的串.确定顺序之后就可以DP了. ...
- XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem A. Arithmetic Derivative
题目:Problem A. Arithmetic DerivativeInput file: standard inputOutput file: standard inputTime limit: ...
- XVII Open Cup named after E.V. Pankratiev Grand Prix of Moscow Workshops, Sunday, April 23, 2017 Problem D. Great Again
题目: Problem D. Great AgainInput file: standard inputOutput file: standard outputTime limit: 2 second ...
- XVII Open Cup named after E.V. Pankratiev Grand Prix of Moscow Workshops, Sunday, April 23, 2017 Problem K. Piecemaking
题目:Problem K. PiecemakingInput file: standard inputOutput file: standard outputTime limit: 1 secondM ...
随机推荐
- Day047--JS BOM介绍, jQuery介绍和使用
内容回顾 DOM 文档对象模型(model) 一个模型就是一个对象(属性和方法 面向对象的三大特性:封装 继承 多态) 为了可扩展性 DOM操作 标签属性操作 获取值 getAttribute() 设 ...
- HDU2859 Phalanx (动态规划)
Today is army day, but the servicemen are busy with the phalanx for the celebration of the 60th anni ...
- 更换gcc工具链
title: 更换gcc工具链 date: 2019/1/16 19:27:51 toc: true --- 更换gcc工具链 下载后解压到一个临时目录先看看文件结构 mkdir tmp tar xj ...
- busybox(二)编译
title: busybox(二)编译 tag: arm date: 2018-11-13 23:14:58 --- busybox(二)编译 解压,源码包在busybox-1.7.0.tar.bz2 ...
- Numpy 系列(十一)- genfromtxt函数
定义输入 genfromtxt的唯一强制参数是数据的源.它可以是字符串,字符串列表或生成器.如果提供了单个字符串,则假定它是本地或远程文件或具有read方法的打开的类文件对象的名称,例如文件或Stri ...
- 分布式监控系统开发【day37】:监控客户端开发(五)
一.目录结构 二.模块方法调用关系总图 三.入口文件main 1.解决了说明问题 1.客户端就干了一件事情,干什么事情 收集数据汇报给服务端? 但是我这个客户端是插件形式2.首先必须要传一个参数,st ...
- 关于微信登录授权获取unionid的方法
前言:微信登录授权是目前普遍存在于小程序的,还有一种静默授权方式是微信提供的但是不推荐使用,由于不同设备登录openid是不同的那么我们应该怎样拿到一个唯一的ID呢,下面做分享 wxml代码 < ...
- Cygwin添加到鼠标右键
From:http://www.cnblogs.com/killerlegend/p/3960112.html 在cygwin中安装chere 管理员权限执行mintty,输入下列命令即可. cher ...
- 深入学习css伪类和伪元素及其用法
前言 CSS的伪类和伪元素在平时的代码中经常会出现,可是一旦别人问你,什么是伪类,什么是伪元素,可能还是不能完整的表述出来,下面我们来一探究竟. 伪类和伪元素定义 伪类用于在页面中的元素处于某个状态时 ...
- 【Java】Java随手记
System.out.printf() : System.out.printf("%d",x); 输出整数 System.out.printf(&quo ...