A KRIŽALJKA
【分析】
这一题只要仔细看题目的话应该是简单的,也相信大家不是来看我怎么花式讲水题的,就直接贴代码了。
【代码】
#include <bits/stdc++.h>
using namespace std;
#define M 40
char a[M],b[M];
int n,m,f=1;
int pos1,pos2;
char mp[M][M];
int main(){
scanf("%s",a+1);
scanf("%s",b+1);
n=strlen(a+1);
m=strlen(b+1);
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++)mp[i][j]='.';
}
for(int i=1;f&&i<=n;i++){
for(int j=1;f&&j<=m;j++){
if(a[i]==b[j]){
f=0;
pos1=j;
pos2=i;
}
}
}
for(int i=1;i<=n;i++)mp[pos1][i]=a[i];
for(int i=1;i<=m;i++)mp[i][pos2]=b[i];
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++)printf("%c",mp[i][j]);
puts("");
}
return 0;
}
B EKO
【分析】
考虑到答案存在单调性,所以就直接二分咯。
想要1A的话还是要注意算md的时候有可能爆int。
【代码】
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define M 1000005
int a[M];
int n,m;
int l,r;
int res;
bool chk(int h){
ll hav=0;
for(int i=1;i<=n;i++){
if(a[i]<=h)continue;
hav+=a[i]-h;
}
return hav>=m;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
r=max(r,a[i]);
}
while(!(l>r)){
int md=1ll*(l+r)/2;
if(chk(md)){
res=md;
l=md+1;
}else r=md-1;
}
printf("%d\n",res);
return 0;
}
C DNA
【分析】
知道题可以考虑贪心和dp,但是,我并没有找出容易的贪心做法,那就换一个路子,dp。
我们定义dp[i][j]表示将1~i全部变成j需要的最小个数。
那么转移方程也就比较容易推出了。
但是比赛的时候没有将这题1A,原因是RE了…
【代码】
#include<bits/stdc++.h>
using namespace std;
#define M 1000005
int dp[2][M];//B 0;A 1
bool mk[M];
char a[M];
int n;
int main(){
scanf("%d",&n);
scanf("%s",a+1);
for(int i=1;i<=n;i++){
bool f=(a[i]=='A');
dp[f][i]=min(dp[f][i-1],dp[!f][i-1]+1);
dp[!f][i]=min(dp[f][i]+1,dp[!f][i-1]+1);
}
printf("%d",dp[1][n]);
return 0;
}
D RAZBIBRIGA
【分析】
花了半天时间看英文题似懂非懂。感谢小C的中文题意。
我们发现,想要组成这样一个首尾相连的矩形,唯一有用的只是一个单词的开头和结尾的字母。
既然有四个起点和终点,那么我们就枚举终态。
不过还要考虑到一些重复算的相同的部分。如何将他们去掉,就看大家各显神通了。
【代码】
#include <bits/stdc++.h>
using namespace std;
#define M 100005
#define ll long long
char a[M][15];
int n,m;
ll ans;
int cnt[28][28];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%s",a[i]+1);
m=strlen(a[1]+1);
for(int i=1;i<=n;i++){
int x=a[i][1]-'A';
int y=a[i][m]-'A';
cnt[x][y]++;
}
for(int i=0;i<26;i++){
for(int j=0;j<26;j++){
for(int k=0;k<26;k++){
for(int p=0;p<26;p++){
int you[28][28];
memset(you,0,sizeof(you));
ll now=cnt[i][j];
you[i][j]++;
now*=1ll*(cnt[j][k]-you[j][k]);
you[j][k]++;
now*=1ll*(cnt[p][k]-you[p][k]);
you[p][k]++;
now*=1ll*(cnt[i][p]-you[i][p]);
if(now<=0)continue;
ans+=now;
}
}
}
}
cout<<ans<<endl;
return 0;
}
E BLOKOVI
【分析】
比赛的时候完全没什么想法。直接敲了30分。
比赛结束后听jiedai大神的思路,感觉智商又下线了。
啦啦啦,我又回来了!
以下是sonytoy大神的证明
**我们假设已知当前积木 i 质量