Educational Codeforces Round 73
A. 2048 Game
题意:给出一个数组,问能不能通过一系列操作(将数组中的两个数相加变成另一个数),使得数组中包含2048,数组中的数全是2的指数,可以则输出YES
思路:只要有两个数比2048小且一样,则合并,直至不存在两个数一样且比2048小,之后看看数组中是否有2048即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int v[maxn],arr[maxn];
int main()
{
int n,t;
cin>>t;
while(t--)
{
cin >> n;
memset(v,0,sizeof(v));
for(int i=1;i<=n;++i){
cin>>arr[i];
if(arr[i]<=10000) v[arr[i]]++;
}
for(int i=1;i<=4096;i*=2){
v[i*2]+=v[i]/2;
}
v[2048]?cout<<"YES"<<endl:cout<<"NO"<<endl;
}
//system("pause");
return 0;
}
B.Knights
题意:输入n表示有一个n*n的方格,方格中马走的路线的两个点如果颜色不一样则会互相攻击,问这个方格是什么样的时候互相攻击的棋子最多,棋子只有white('W')和black('B')两种;输出该方格
分析:注意到一点,马无论怎么走,其横纵坐标的增加减少值总有一个是偶数,一个数奇数,其和一定为奇数。所以当我们将一个点放入'B'
时,其周围点的横纵坐标之和减去该点的横纵坐标之和为奇数的一定时'W'
;由此可得:点横纵坐标之和为奇数的是一种棋,为偶数的是另一种棋;
#include <bits/stdc++.h>
using namespace std;
const int maxn=110;
int n;
char s[maxn][maxn];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if((i&1)&&(j&1)) cout<<'W';
else if(!(i&1)&&!(j&1)) cout<<'W';
else cout<<'B';
}
cout<<endl;
}
}
C. Perfect Team
题意:三类人每类人的个数给出,问最多有多少只队伍中包含至少一名第一类和一名第二类的人
分析:取第一类和第二类人数的较小值t;判断3*t
和a+b+c
的大小,前者大则总人数/3;否则答案即为t;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main()
{
int T,a,b,c,tot;
scanf("%d",&T);
while (T--){
tot=0;
scanf("%d %d %d",&a,&b,&c);
int t=min(a,b),tot=a+b+c;
if(t*3>=tot){
printf("%d\n",tot/3);
}
else{
printf("%d\n",t);
}
}
//system("pause");
}
D. Make The Fence Great Again
题意:有一列栏杆,给出长度和每修高1个单位的花费,问当所有相邻的栏杆都不相邻时修栏杆的最小花费。
分析:很明显的dp题,且每处的栏杆至多增加2个单位,所以设dp[i][j]
表示前 i 个栏杆第 i 个栏杆修高 j 个单位的最小花费;很容易确定初状态和转移方程,分为now==pre
,now==pre-1
,now==pre-2
,now-1==pre
,now-2==pre
,other
六种情况,分别转移即可;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int maxn=3e5+10;
const ll inf=1e18+9;
pll arr[maxn];
ll dp[maxn][3];
int T,n;
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i){
for(int j=0;j<=2;++j){
dp[i][j]=0;
}
}
for (int i=1;i<=n;++i) scanf("%lld %lld",&arr[i].first,&arr[i].second);
dp[1][0]=0;
dp[1][1]=arr[1].second;
dp[1][2]=arr[1].second*2;
for(int i=2;i<=n;++i){
if(arr[i].first==arr[i-1].first){
dp[i][0]=min(dp[i-1][1],dp[i-1][2]);
dp[i][1]=min(dp[i-1][0],dp[i-1][2])+arr[i].second;
dp[i][2]=min(dp[i-1][0],dp[i-1][1])+2*arr[i].second;
}
else if(arr[i].first==arr[i-1].first+1){
dp[i][0]=min(dp[i-1][0],dp[i-1][2]);
dp[i][1]=min(dp[i-1][0],dp[i-1][1])+arr[i].second;
dp[i][2]=min(min(dp[i-1][0],dp[i-1][1]),dp[i-1][2])+2*arr[i].second;
}
else if(arr[i].first==arr[i-1].first+2){
dp[i][0]=min(dp[i-1][0],dp[i-1][1]);
dp[i][1]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+arr[i].second;
dp[i][2]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+2*arr[i].second;
}
else if(arr[i].first+1==arr[i-1].first){
dp[i][0]=min(min(dp[i-1][0],dp[i-1][1]),dp[i-1][2]);
dp[i][1]=min(dp[i-1][1],dp[i-1][2])+arr[i].second;
dp[i][2]=min(dp[i-1][0],dp[i-1][2])+2*arr[i].second;
}
else if(arr[i].first+2==arr[i-1].first){
dp[i][0]=min(min(dp[i-1][0],dp[i-1][1]),dp[i-1][2]);
dp[i][1]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+arr[i].second;
dp[i][2]=min(dp[i-1][1],dp[i-1][2])+2*arr[i].second;
}
else{
dp[i][0]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]));
dp[i][1]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+arr[i].second;
dp[i][2]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+2*arr[i].second;
}
}
printf("%lld\n",min(dp[n][0],min(dp[n][1],dp[n][2])));
}
//system("pause");
}