Educational Codeforces Round 85 (Rated for Div. 2)ABCD
A - Level Statistics
题意:
给n个ai,bi,ai代表尝试次数,bi代表成功次数,ai,bi是累计下来计数,问是否合理,不合理输出no,反之yes
思路:
满足ai>bi 同时ai<ai-1 ,bi<bi-1 以及ai-(ai-1)>bi-(bi-1)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=1e4+10;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t;
int n,m;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int f=0,z=0,y=0;
for(it i=0;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
if(a<z|| b<y|| a<b ||(b-y>a-z)){f=1;}
z=a;y=b;
}
if(f){printf("NO\n");}
else{printf("YES\n");}
}
return 0;
}
B - Middle Class
题意:
给n,m,在给n个数字,问这些数字,在选择一些数字使其变成平均值的操作后,最多有多少个数字超过m
思路:
把大于m的数字多余的部分累加,不大于m的存进数组a[],从大到小排序,那些累加的数据能使得多少m-ai大于或者等于
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=1e5+10;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t,n;
ll m,a[maxn];
bool cmp(ll a,ll b){
return a>b;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%lld",&n,&m);
ll sum=0;int ge=0,k=0;
for(it i=1;i<=n;i++){
ll zhi;
scanf("%lld",&zhi);
if(zhi>=m){
sum+=(zhi-m);ge++;
}
else{
a[k++]=zhi;
}
}
sort(a,a+k,cmp);int kk=0;//cout<<ge<<sum<<endl;
while(sum){
if(kk==k){break;}
if(m-a[kk]>sum){break;}
sum-=(m-a[kk]);ge++;kk++;
}
printf("%d\n",ge);
}
return 0;
}
C - Circle of Monsters
题意:
给n个ai,bi的数据,ai代表生命值,bi代表死后(生命值小于等于0)对下一个相邻的a造成的伤害,凡是死了就会造成伤害,bn是对a1的。每次的攻击生命值减一,问最小的攻击次数
思路:
先用cnt[]存bi对ai+1的伤害,如果cnt[i]小于0,就变成0。累加cnt得到sum,sum-cnt[i]+a[i]就是点爆第一个位置后需要的攻击次数,但是因为数据3e5*1e12,所以要开1e18(我这被hack了,导致我无奈只能去hack别人了)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
const int maxn=3e5+10;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t,n;
ll a[maxn],b[maxn],c[maxn];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(it i=1;i<=n;i++){
scanf("%lld%lld",&a[i],&b[i]);
}
ll sum=0,zhi=1e18;//zhi的值3e5*1e12
c[1]=a[1]-b[n];if(c[1]<0){c[1]=0;}
sum+=c[1];
for(it i=1;i<n;i++){
c[i+1]=a[i+1]-b[i];
if(c[i+1]<0){c[i+1]=0;}
sum+=c[i+1];
}
for(it i=1;i<=n;i++){
ll ans=sum-c[i]+a[i];
zhi=min(zhi,ans);
}
printf("%lld\n",zhi);
}
return 0;
}
D - Minimum Euler Cycle
题意:
给n,l,r,n<=1e5,1<=l<r<=n*(n-1) ,r-l+1<=1e5。给出一个序列,满足一个条件,举个例子,3的话,12 13 23 21 31 32都要有,只出现一次。组成最小字典序的序列,121323321;4的话就是1213142324341。问最小的序列的l,r是多少。
思路:
规律就是,12 13 14 …1n 23 24 …2n 34 …3n …n-1n 最后多出1。那么只要找他在哪个位置就可以了。就跟上次aaaabb有点相似,找到第一个值得位置,然后输出
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 10000000070000
const int maxn=1e5+10;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t;
ll n,l,r;
int ans[maxn];
int main(){
scanf("%d",&t);
while (t--){
scanf("%lld%lld%lld",&n,&l,&r);
ll s = 0;int i,j;
for(i=1;i<=n;i++){
ll t = s + 1ll*2*(n-i);
if (t < l){s = t; continue;}
if (s < l && t >= l){
if (l%2 == 1){
int L = (l - s)/2 + 1 + i;
if (t >= r){
int R = (r-s)/2 + i;
for(j=L;j<=R;j++){
printf("%d %d ",i,j);
}
if ((r-s)%2 == 1) printf("%d ",i);
s = t;
break;
}
for(j=L;j<=n;j++){
printf("%d %d ",i,j);
}
}
else{
int L = (l - s)/2 + i;
printf("%d ",L);;
if (t >= r){
int R = (r-s)/2 + i;
for(j=L+1;j<=R;j++){
printf("%d %d ",i,j);
}
if ((r-s)%2 == 1) printf("%d ",i);
s = t;
break;
}
for(j=L+1;j<=n;j++){
printf("%d %d ",i,j);
}
}
s = t;
continue;
}
if (t < r){
for(j=i+1;j<=n;j++){
printf("%d %d ",i,j);
}
s = t; continue;
}
if (s < r && t >= r){
int R = (r - s)/2 + i;
for(j=i+1;j<=R;j++){
printf("%d %d ",i,j);
}
if ((r-s)%2 == 1) printf("%d ",i);
s = t;
}
}
if (s < r) printf("1 ");;
printf("\n");
}
return 0;
}
补题