B.Coffee Chicken
对于 S ( n ) S(n) S(n),考虑某个字母是从 S ( n − 1 ) S(n-1) S(n−1)转移还是从 S ( n − 2 ) S(n-2) S(n−2)转移
#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 10005
using namespace std;
int T,n,q,p,t;
long long k,kk;
long long f[N];
string ch[3];
int main()
{
scanf("%d",&T);
f[1] = 6; f[2] = 7; t = 2;
while (f[t] < 1e12) {t++; f[t] = f[t-1] + f[t-2];}
ch[1] = "COFFEE"; ch[2] = "CHICKEN";
while (T--)
{
scanf("%d%lld",&n,&k); kk = k;
q = 10;
while (q--)
{
p = min(n,t);
if (k > f[p]) break;
while (p > 2)
{
if (k <= f[p-2]) p = p - 2; else
{
k = k - f[p-2];
p = p - 1;
}
}
//cout<<p<<" "<<k<<endl;
printf("%c",ch[p][k-1]);
kk++; k = kk;
}
printf("\n");
}
return 0;
}
E.Hilbert Sort
第一次抢下一血好激动啊
大概就是每次四分,递归到某一块
然后根据当前的起点和终点(op=1/2/3/4)直接暴力手算找出四块的op
其实应该就是一个分形
#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 1000005
using namespace std;
struct www{int x,y; long long v;} f[N];
int n,k,len,i;
bool cmp(const www &a,const www &b) {return a.v < b.v;}
long long dfs(int op,int x,int y,int len)
{
if (len == 1) return 1;
int len2 = len / 2;
int op2;
long long d = 1ll * (len / 2) * (len / 2);
if (x <= len2 && y <= len2) op2 = 1;
if (x <= len2 && y > len2) op2 = 2;
if (x > len2 && y <= len2) op2 = 3;
if (x > len2 && y > len2) op2 = 4;
if (x > len2) x -= len2;
if (y > len2) y -= len2;
if (op == 1)
{
if (op2 == 1) return dfs(2,x,y,len2);
if (op2 == 3) return dfs(1,x,y,len2) + d;
if (op2 == 4) return dfs(1,x,y,len2) + d * 2;
if (op2 == 2) return dfs(3,x,y,len2) + d * 3;
}
if (op == 2)
{
if (op2 == 1) return dfs(1,x,y,len2);
if (op2 == 2) return dfs(2,x,y,len2) + d;
if (op2 == 4) return dfs(2,x,y,len2) + d * 2;
if (op2 == 3) return dfs(4,x,y,len2) + d * 3;
}
if (op == 3)
{
if (op2 == 4) return dfs(4,x,y,len2);
if (op2 == 3) return dfs(3,x,y,len2) + d;
if (op2 == 1) return dfs(3,x,y,len2) + d * 2;
if (op2 == 2) return dfs(1,x,y,len2) + d * 3;
}
if (op == 4)
{
if (op2 == 4) return dfs(3,x,y,len2);
if (op2 == 2) return dfs(4,x,y,len2) + d;
if (op2 == 1) return dfs(4,x,y,len2) + d * 2;
if (op2 == 3) return dfs(2,x,y,len2) + d * 3;
}
}
int main()
{
scanf("%d%d",&n,&k);
len = 1 << k;
fo(i,1,n)
{
scanf("%d%d",&f[i].x,&f[i].y);
f[i].v = dfs(1,f[i].x,f[i].y,len);
}
sort(f+1,f+n+1,cmp);
fo(i,1,n) printf("%d %d\n",f[i].x,f[i].y);
return 0;
}
F.Popping Balloons
没想到暴力可以艹过去
考虑暴力:
O
(
n
2
)
O(n^2)
O(n2)枚举水平和竖直的中间一枪,去掉重复情况
优化:水平方向从大到小枚举,竖直方向也从大到小枚举
剪枝:如果当前不去重的答案已经小于目前的ans就直接break
#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 100005
using namespace std;
struct node
{
int x,y;
bool operator < (const node &rhs) const
{
return x<rhs.x || (x==rhs.x && y<rhs.y);
}
};
struct val{int v,p;} numx[N],numy[N];
map<node,int> mp;
int n,r,i,j,x,y,res,linex,liney,v1,v2;
int num1[N],num2[N];
bool cmp(const val &a,const val &b) {return a.v > b.v;}
int check(int x,int y)
{
int ans = 0;
int i,j,xx,yy;
fo(i,-1,1)
fo(j,-1,1)
{
xx = x + r * i;
yy = y + r * j;
node p = node{xx,yy};
ans += mp[p];
}
return ans;
}
int main()
{
scanf("%d%d",&n,&r);
fo(i,1,n)
{
scanf("%d%d",&x,&y);
num1[x]++;
num2[y]++;
node p = node{x,y};
mp[p]++;
}
fo(i,0,1e5)
{
numx[i].p = numy[i].p = i;
numx[i].v = num1[i];
if (i-r >= 0) numx[i].v += num1[i-r];
if (i+r <= 1e5) numx[i].v += num1[i+r];
numy[i].v = num2[i];
if (i-r >= 0) numy[i].v += num2[i-r];
if (i+r <= 1e5) numy[i].v += num2[i+r];
}
sort(numx,numx+100000+1,cmp);
sort(numy,numy+100000+1,cmp);
res = 0;
fo(i,0,1e5)
{
linex = numx[i].p; v1 = numx[i].v;
fo(j,0,1e5)
{
liney = numy[j].p; v2 = numy[j].v;
if (v1 + v2 < res) break;
res = max(res,v1+v2-check(linex,liney));
}
}
cout<<res<<endl;
return 0;
}
H.Stammering Chemists
先判掉有度为4的、两个度为3的、最大度为2的情况
然后判断度为3的那个点连出去的三个点的度是112还是122
#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 10
using namespace std;
int T,i,j,x,y;
int f[N][N],num[N],d[N];
int main()
{
scanf("%d",&T);
while (T--)
{
fo(i,1,6) fo(j,1,6) f[i][j] = 0;
fo(i,1,5)
{
scanf("%d%d",&x,&y);
f[x][y] = f[y][x] = 1;
}
fo(i,1,6)
{
d[i] = 0;
fo(j,1,6) d[i] += f[i][j];
}
num[1] = num[2] = num[3] = num[4] = 0;
fo(i,1,6) num[d[i]]++;
if (num[4] > 0) {printf("2,2-dimethylbutane\n"); continue;}
if (num[3] == 2) {printf("2,3-dimethylbutane\n"); continue;}
if (num[3] == 0) {printf("n-hexane\n"); continue;}
x = 0;
fo(i,1,6)
if (d[i] == 3)
{
fo(j,1,6)
if (f[i][j] == 1)
{
if (d[j] == 2) x++;
}
}
if (x == 1) {printf("2-methylpentane\n"); continue;}
if (x == 2) {printf("3-methylpentane\n"); continue;}
}
return 0;
}