CF1551D1 Domino (easy version)
考点:数学+分类讨论。
先考虑竖着的情况。显然每次选择两个相邻的列使得行数减少 1
。最后每一列的行数都必须是偶数。分奇偶讨论即可。
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define All(a) a.begin(),a.end()
using namespace std;
int cnt[105];
int main() {
int T; cin>>T;
while(T--) {
int n,m,k,ok=0; cin>>n>>m>>k; for(int i=1;i<=m;i++) cnt[i]=n;
if(n%2==0) printf("%s\n",(k%2==0&&n*(m/2)>=k)?"yes":"no");
else printf("%s\n",(m%2==0&&(k-m/2)%2==0&&k>=m/2)?"yes":"no");
}
}
CF1551D2 Domino (hard version)
考点:模拟
根据四色定理可知,方案一定有解。
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define All(a) a.begin(),a.end()
using namespace std;
int cnt[105],n,m,k;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
char ans[105][105];
bool ch[26];
void paint(int x,int y,int x2,int y2) {
memset(ch,0,sizeof(ch));
for(int i=0;i<4;i++) {
int tx=x+dx[i],ty=y+dy[i];
if(ans[tx][ty]) ch[ans[tx][ty]-'a']=1;
}
for(int i=0;i<4;i++) {
int tx=x2+dx[i],ty=y2+dy[i];
if(ans[tx][ty]) ch[ans[tx][ty]-'a']=1;
}
for(int i=0;i<26;i++)
if(!ch[i]) {
ans[x][y]=ans[x2][y2]='a'+i;
return;
}
}
void output() {
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
printf("%c",ans[i][j]);
}
printf("\n");
}
}
int main() {
int T; cin>>T;
while(T--) {
int ok=0; cin>>n>>m>>k; for(int i=1;i<=m;i++) cnt[i]=n;
memset(ans,0,sizeof(ans));
if(n%2==0) {
if(k%2==0&&n*(m/2)>=k) {
printf("YES\n");
for(int i=1;i<n;i+=2) {
for(int j=1;j<m;j+=2) {
if(k) {
paint(i,j,i,j+1);
paint(i+1,j,i+1,j+1);
k-=2;
}
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(!ans[i][j]) {
paint(i,j,i+1,j);
}
}
}
output();
}
else {
printf("NO\n");
}
}
else {
if(m%2==0&&k>=m/2&&(k-m/2)%2==0) {
printf("YES\n");
for(int i=1;i<m;i+=2) {
paint(1,i,1,i+1);
k--;
}
for(int i=2;i<n;i+=2) {
for(int j=1;j<m;j+=2) {
if(k) {
paint(i,j,i,j+1);
paint(i+1,j,i+1,j+1);
k-=2;
}
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(!ans[i][j]) {
paint(i,j,i+1,j);
}
}
}
output();
}
else {
printf("NO\n");
}
}
}
}
CF1551E Fixed Points
考点:dp状态
。 设 dp[i][j]
表示前 i
个数,i
的排名为 j
的最大匹配数,那么答案显然可以算。
转移方程为:dp[i][j] = max(dp[i-1][j], dp[i-1][j-1] + (j == a[i]))
。
CF1551F Equidistant Vertices
直接 n^3
暴力计算即可。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define PII pair<int,int>
#define All(a) a.begin(),a.end()
using namespace std;
const int mx=1e9+7;
const int mod=1e9+7;
int n,k,dep[105];
ll res,c[105][105],f[105][105],dp[105][105];
vector<int> g[105];
//k>=4 时比较复杂
//换根dp + 组合数学
void dfs(int x,int fa) {
f[x][0]=1;
for(auto y:g[x]) {
if(y==fa) continue;
dfs(y,x);
for(int i=1;i<=n;i++) {
f[x][i]+=f[y][i-1];
}
}
}
int main() {
for(int i=0;i<=100;i++) c[i][0]=1;
for(int i=1;i<=100;i++) {
for(int j=1;j<=100;j++) {
c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
}
int T; scanf("%d",&T);
while(T--) {
memset(f,0,sizeof(f)); res=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) g[i].clear();
for(int i=1;i<n;i++) {
int x,y; scanf("%d%d",&x,&y);
g[x].push_back(y),g[y].push_back(x);
}
if(k==2) {
printf("%d\n",n*(n-1)/2);
continue;
}
for(int u=1;u<=n;u++) {
for(int i=1;i<=n;i++) {
for(int j=0;j<=n;j++) {
f[i][j]=0;
}
}
dfs(u,0);
for(int i=1;i<=n;i++) {
for(int j=1;j<=k;j++) dp[i][j]=0;
dp[i][0]=1;
}
for(auto v:g[u]) {
for(int i=1;i<=n;i++) {
for(int j=k;j>=1;j--) {
dp[i][j]=(dp[i][j]+dp[i][j-1]*f[v][i-1]%mod)%mod;
}
}
}
for(int i=1;i<=n;i++) res=(res+dp[i][k])%mod;
}
printf("%lld\n",res);
}
}