Codeforces Round #560 (Div. 3)
第一次补完一场cf
A:给数字A(由01组成的十进制)和b,c,求A%10^b=10^c最少要翻转A几位。
字符串瞎模拟一下即可。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
int main(){
int n,x,y;scanf("%d%d%d",&n,&y,&x);
string s;cin>>s;int ans=0;
for(int i=n-1;i>=n-y;i--){
if(i==n-x-1)continue;
if(s[i]!='0')ans++;
}
if(s[n-x-1]=='0')ans++;
printf("%d",ans);
return 0;
}
B:有n场比赛,第n天打多于n个问题的比赛,问怎么安排比赛使能打的比赛场次最多,求最多的场次。
multiset瞎搞即可
#include<bits/stdc++.h>
using namespace std;
#define LL long long
multiset<int>s;
int main(){
int n;scanf("%d",&n);for(int i=1;i<=n;i++){
int sc;scanf("%d",&sc);s.insert(sc);
}
int ans=0;
for(int i=1;i<=n;i++){
multiset<int>::iterator it;
it=s.lower_bound(i);
if(it!=s.end()){
ans++;
s.erase(it);
}
}
printf("%d",ans);
return 0;
}
C:给一个字符串,要求删除几个,使得第2*i位和第2*i-1位不一样,求最少删几个。
贪心从左往右删即可
#include<bits/stdc++.h>
using namespace std;
#define LL long long
string s;
bool vis[1000000];
int main(){
int n;cin>>n>>s;
int ans=0;
for(int i=0;i<n-1;){
int j;
for(j=i+1;j<n;j++){
if(s[i]==s[j]){ans++;vis[j]=1;}
else {break;}
}
i=j+1;
}
if((ans+n)%2){ans++;}
cout<<ans<<endl;int p=1;
for(int i=0;i<n;i++){
if(vis[i]==0&&p<=n-ans)cout<<s[i],p++;
}
return 0;
}
D:给一个数组,判断其是否为n的(almost all因子数组),almost all的因子数组是包含n所有因子(除1和n)的数组。
先sort,假设是满足题意的,那么第一个和最后一个数字相乘就是n,那么求出n的所有因子,再进行比对即可判断。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int MXN = 305;
LL gcd(LL x,LL y){
if(y==0)return x;
return gcd(y,x%y);
}
LL d[MXN];
vector<LL>v;
int main(){
int T;cin>>T;while(T--){
int n;scanf("%d",&n);for(int i=1;i<=n;i++){
int sc;scanf("%d",&sc);d[i]=sc;
}
LL x=1;v.clear();
sort(d+1,d+1+n);
x=d[1]*d[n];
for(LL i=2;i*i<=x;i++){
if(x%i==0){
v.push_back(i);
v.push_back(x/i);
}
}
if(v[v.size()-1]==v[v.size()-2])v.pop_back();
sort(v.begin(),v.end());
if(v.size()!=n){puts("-1");continue;}
int k=0;
for(int i=1;i<=n;i++){
if(v[i-1]!=d[i]){k=1;break;}
}
if(k){puts("-1");continue;}
printf("%lld\n",x);
}
return 0;
}
E:给两个数组A和B,B可以交换顺序,使得最小,其中
一开始没发现A不能动,真的zz 对于一个位置p,那么他对答案的贡献是要乘上p*(n+1-p),显然那么A乘上p*(n+1-p)再从小到大排序, B再重大到小排,这样一定使得答案最小。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int MXN = 1e6;
const int mod = 998244353;
LL a[MXN],b[MXN],c[MXN];
bool cmp(int x,int y){return x>y;}
int main(){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++){
LL tt=(LL)i*(LL)(n+1-i);
scanf("%d",&a[i]);
a[i]=a[i]*tt;
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
sort(a+1,a+1+n);sort(b+1,b+1+n,cmp);
LL ans=0;
for(int i=1;i<=n;i++){
ans=ans+a[i]%mod*b[i]%mod;
ans%=mod;
}
printf("%lld\n",ans);
return 0;
}
F1和F2,F2数据大,直接写F2
F2:第i天有i元,要买n个东西,第i个东西要ki个,然后某几天会对某些商品打对折,求最少需要几天可以买到所有的东西。
二分第几天,然后贪心的攒钱,对于每一件商品都再最后一天去买,这样保证可以买到的打折商品数量最多。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL mod = 1000000007;
const int MXN = 5e5+5;
int k[MXN];int last[MXN],need[MXN],d[MXN],t[MXN];
vector<int>v[MXN];
bool check(int x,int n,int m){
for(int i=1;i<=n;i++)need[i]=k[i],last[i]=0;
for(int i=1;i<=x;i++)v[i].clear();//出错
for(int i=1;i<=m;i++){
if(d[i]<=x)
last[t[i]]=max(last[t[i]],d[i]);//出错
}
for(int i=1;i<=n;i++){
if(last[i]>0)
v[last[i]].push_back(i);//第last[i]天有第i个物品
}
int money=0;
for(int i=1;i<=x;i++){
money++;
for(auto it:v[i]){
int lim=min(money,need[it]);
money-=lim;need[it]-=lim;
}
}
for(int i=1;i<=n;i++){money-=2*need[i];}
return money>=0;
}
int main(){
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&k[i]);
for(int i=1;i<=m;i++){scanf("%d%d",&d[i],&t[i]);}
int l=0,r=4e5+10,ans=-1;
while(l<=r){
int mid=(l+r)/2;
if(check(mid,n,m)){
ans=mid;
r=mid-1;
}
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}
细节啊细节,好菜啊......