Codeforces Round #587 (Div. 3):点击进入新世界
A. Prefixes(模拟)
原题链接:http://codeforces.com/contest/1216/problem/A
思路:
- 题目要求给出字符串偶数长度的前缀必须有相同数目的’a’和‘b’,要求出最小修改次数和修改后的字符串。
- 直接模拟。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int manx=2e6+5;
char c[manx];
int a=0,b=0,ans=0;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>c[i];
if(c[i]=='a') a++;
else if(c[i]=='b') b++;
if(i%2==0){
if(a==b) continue;
else if(a>b) c[i]='b',a=0,b=0,ans++;
else if(a<b) c[i]='a',a=0,b=0,ans++;
}
}
cout<<ans<<endl;
for(int i=1;i<=n;i++)
cout<<c[i];
return 0;
}
B. Shooting(贪心)
原题链接:http://codeforces.com/contest/1216/problem/B
思路:
- 题目给定射穿罐子所需消耗的能量,每次消耗能量的总量计算公式为 s[i] = a[i] *(i-1) +1,要求最小消耗的能量,和输出射穿罐子的序号顺序。
- 直接把a进行由大到小排序,然后依次相加,即可。这里我是用结构体储存消耗的能量和罐子的序号。
AC代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int manx=3e5+5;
struct node{
int nums,w;
}a[manx];
bool cmp(node a, node b)
{
if(a.w!=b.w)
return a.w>b.w;
else return a.nums<b.nums;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
a[i].nums=i;
scanf("%d",&a[i].w);
}
sort(a+1,a+1+n,cmp);
int ans=1;
for(int i=2;i<=n;i++)
ans+=a[i].w*(i-1)+1;
cout<<ans<<endl;
for(int i=1;i<=n;i++) cout<<a[i].nums<<" ";
return 0;
}
C. White Sheet(思维)
原题链接:http://codeforces.com/contest/1216/problem/C
思路:
- 给定一张白纸的坐标和两张黑纸的坐标依次叠放,问是否能够看到白纸,能输出YES否则输出NO。(这里的看到是指能否从缝隙看到,则要考虑小数而不能单单考虑整数)
- 在输入一张黑纸的时候对白纸 未覆盖的部分 的坐标进行更新,然后判断是否完全覆盖即可。
AC代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
const int manx=1e6+5;
int a[manx],b[manx];
int main()
{
int a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c4,c3,flag=1;
cin>>a1>>a2>>a3>>a4;
cin>>b1>>b2>>b3>>b4;
cin>>c1>>c2>>c3>>c4;
if(b1<=a1&&b2<=a2&&b3>=a3&&b4>=a4)
flag=0;
else {
if(b1<=a1&&b2<=a2&&b3>=a3) a2=max(a2,b4);
if(b1<=a1&&b3>=a3&&b4>=a4) a4=min(a4,b2);
if(b1<=a1&&b2<=a2&&b4>=a4) a1=max(a1,b3);
if(b3>=a3&&b2<=a2&&b4>=a4) a3=min(a3,b1);
}
if(c1<=a1&&c2<=a2&&c3>=a3&&c4>=a4)
flag=0;
if(flag) printf("YES");
else printf("NO");
return 0;
}
D. Swords(GCD)
原题链接:http://codeforces.com/contest/1216/problem/D
思路:
- 给定剩下剑的数量,求偷窃的人数的最小值和每个人偷窃的数量。(每个人偷窃剑的类型必须是同一类型)
- 要使y最小,题目所求 x应为剩下每种剑的数量的最大值。
- 设s 为被偷剑的总量 ,则s+= (max(a[i]) - a[i] ) 。
- 有 y * z =s , 要使 y 最小, 即 使 z 尽可能大, 因为每个人偷窃剑的类型必须使同一类型 , 所以即求即求每把剑被偷数量的最大公约数。
- 关于__gcd函数可参考:点这里 有很多STL你未见过的函数~
AC代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int manx=2e5+5;
typedef long long ll;
ll a[manx];
ll s=0,z=0,y,ans;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),ans=max(ans,a[i]);
for(int i=1;i<=n;i++)
{
s+=ans-a[i];
z=__gcd(z,ans-a[i]);
}
cout<<s/z<<" "<<z;
return 0;
}
第一次打CF,掉了82分,菜…
留着坑,最近有点忙,来不及补题,等国庆补?
待续。