Consest:https://codeforces.com/contest/1154
这场打的是真惨啊C题卡了半天,D题样例始终对不上,E题满脑子骚操作就是不会写。被吊打,疯狂掉分,滚粗CF。
这次的题好多模拟啊。。。
A. Restoring Three Numbers(数学)
题目链接:https://codeforces.com/contest/1154/problem/A
题目大意:三个数a,b,c,然后你有a+b,a+c,b+c,a+b+c四个结果。让你求出原来的a,b,c;
思路:四个方程三个未知数,联立得出a||b||c=(a+b+c)-(a+b)||(a+c)||(b+c);输出即可。
ACCode:
int main(){
int a[5];
for(int i=1;i<=4;++i){
scanf("%d",&a[i]);
}sort(a+1,a+1+4);
int x1=a[4]-a[1];
int x2=a[4]-a[2];
int x3=a[4]-a[3];
printf("%d %d %d\n",x1,x2,x3);
}
B. Make Them Equal(暴力)
题目链接:https://codeforces.com/contest/1154/problem/B
题目大意:给出n个数的数组a,让你选择一个数d对于所有的a[i](加上||减去||d||不改变)之后变成一个数。输出最小的d
思路:由于数据范围非常小,暴力就好了。
ACCode:
// luogu-judger-enable-o2
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define Pair pair<int,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
// register
const int MAXN=1e4+10;
const int INF32=0x3f3f3f3f;
const LL INF64=0x3f3f3f3f3f3f3f3f;
const int MOD=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);
int a[MAXN];
int n;
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}sort(a+1,a+1+n);
if(a[1]==a[n]){
printf("0\n");
continue;
}
int ans=INF32;
for(int i=0;i<=200;++i){//mid is i
int res=INF32;
for(int j=1;j<=n;++j){
if(a[j]==i) continue;
if(res==INF32) res=abs(a[j]-i);
if(res!=abs(a[j]-i)){
res=-1;
break;
}
}
if(res!=-1) ans=min(ans,res);
}printf("%d\n",ans==INF32?-1:ans);
}
}
C. Gourmet Cat(模拟)
题目链接:https://codeforces.com/contest/1154/problem/C
题目大意:三种食物,鱼在周1,4,7吃,兔子在周2,6吃,鸡在周3,5吃。问一开始分别准备了a,b,c数量的食材。最多能够坚持多少天不不充食材。输出最长的天数。(一周过完跟着一周)
思路:首先一周分别花费3,2,2。所以按照这个数量得出多少个整周。然后对于剩下的小天数分别计算即可。(辣鸡的我只会枚举,据说有大佬一个循环就出来了,以后再看吧QAQ)总共4*3*3=36种情况好难受。
ACCode:
int main(){
int a,b,c;
while(~scanf("%d%d%d",&a,&b,&c)){
int minn=min(a/3,min(b/2,c/2));
a=a-3*minn;b=b-2*minn;c=c-2*minn;
int ans=minn*7,last=min(a,min(b,c));
if(a==0){
if(b==0){
if(c==0) ans=ans;
else ans+=1;
}
else{
if(c==0) ans+=1;
else ans+=2;
}
}
else if(a==1){
if(b==0){
if(c==0) ans+=1;
else if(c==1) ans+=2;
else ans+=3;
}
else if(b==1){
if(c==0) ans+=2;
else if(c==1) ans+=3;
else ans+=4;
}
else{
if(c==0) ans+=2;
else if(c==1) ans+=3;
else ans+=5;
}
}
else if(a==2){
if(b==0){
if(c==0||c==1) ans+=2;
else ans+=3;
}
else if(b==1){
if(c==0) ans+=3;
else if(c==1) ans+=4;
else ans+=5;
}
else{
if(c==0) ans+=4;
else if(c==1) ans+=5;
else ans+=6;
}
}
else{
if(b==0){
if(c==0||c==1) ans+=2;
else ans+=3;
}
else if(b==1){
if(c==0) ans+=3;
else if(c==1) ans+=5;
else ans+=6;
}
else{
if(c==0) ans+=4;
else if(c==1) ans+=6;
else ans+=7;
}
}printf("%d\n",ans);
}
}
D. Walking Robot(模拟)
题目链接:https://codeforces.com/contest/1154/problem/D
题目大意:一个n长度的路段,0代表没有阳光,1代表有阳光。机器人有两块电池a,b(容量)电池一开始的时候是满的。机器人向前走一步需要花费一格电,当机器人走过1道路的时候,可以选择电池a减少1电量,电池b加1点电量(但是b如果是满的就无法增加)。当经过0道路时,可以选择消耗a电池||b电池。问机器人最多走多远。
思路:模拟即可。很明显,先要用电池b的点。
ACCode:
// luogu-judger-enable-o2
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define Pair pair<int,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ˮӡ
//std::ios::sync_with_stdio(false);
// register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const LL INF64=0x3f3f3f3f3f3f3f3f;
const int MOD=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);
int s[MAXN];
int n,b,a;
int main(){
while(~scanf("%d%d%d",&n,&a,&b)){
int c=a,d=b;
for(int i=1;i<=n;++i){
scanf("%d",&s[i]);
}int flag=0;
int i;
for(i=1;i<=n;++i){
if(s[i]){
if(d<b){
if(c>0){
++d;--c;
}
else{//c==0
--d;
}
}
else{//d==b
--d;
}
}
else{//0
if(d>0) --d;
else --c;
}
if(c==0&&d==0) break;
}printf("%d\n",i==n+1?n:i);
}
}
E. Two Teams(模拟)
题目链接:https://codeforces.com/contest/1154/problem/E
题目大意:n个元素的数组,每个元素都有自己的权值,两个人轮流从中选择最大的元素,同时选择最大元素为中心,k半径的元素,选择出的元素被移除数组。问最后每个元素的归属。
思路:一开始没什么思路,毕竟数组有点大,而且也不知道怎么搞,后来想起了之气yy的一个算法,使用两个数组L,R记录该节点被L~R区间包含,然后之后碰到该节点之后直接跳过就好了。没想到就过了,后来估算了一下复杂度,似乎删掉之后就变少了。
ACCode:
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define Pair pair<int,int>
#define M_P(a,b) make_pair(a,b)
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
// register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
int a[MAXN],Vis[MAXN];
int L[MAXN],R[MAXN];
int Res[MAXN];
Pair b[MAXN];
int n,k;
int Cmp(Pair x,Pair y){
return x.second>y.second;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i) L[i]=R[i]=i;
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
b[i]=make_pair(i,a[i]);
}sort(b+1,b+1+n,Cmp);
for(int i=1,Kind=1;i<=n;++i){
// cout<<b[i].first<<" "<<b[i].second<<endl;
if(Vis[b[i].first]) continue;
int temp=b[i].first;
Vis[temp]=Kind&1?1:2;Kind++;//ˢ�¸õ�
int ql=temp,qr=temp,tot=0;
for(int j=1,l=1;j<=k;++j){
int tempx=temp-l;
while(tempx>=1&&Vis[tempx]) tempx=L[tempx]-1;//���ڣ��ߵ��߾�
if(tempx==0){
ql=1;break;
}Res[++tot]=tempx;
Vis[tempx]=Vis[temp];
l=temp-tempx;ql=tempx;
}
for(int j=1,r=1;j<=k;++j){
int tempx=temp+r;
while(tempx<=n&&Vis[tempx]) tempx=R[tempx]+1;
if(tempx==n+1){
qr=n;break;
}Res[++tot]=tempx;
Vis[tempx]=Vis[temp];
r=tempx-temp;qr=tempx;
}
for(int j=1;j<=tot;++j){
L[Res[j]]=ql;R[Res[j]]=qr;
}L[temp]=ql;R[temp]=qr;
// cout<<endl<<b[i].first<<" "<<b[i].second<<": "<<endl;
// for(int i=1;i<=n;++i){
// cout<<Vis[i];//<<L[i]<<" "<<R[i]<<endl;
// }
}
for(int i=1;i<=n;++i){
printf("%d",Vis[i]);
}printf("\n");
}
F. Shovels Shop(简单DP)
题目链接:https://codeforces.com/contest/1154/problem/F
题目大意:给出n个铲子的价格,m个优惠方式,要买k个铲子。优惠是满a个,花费最少的b个就会免费。问最少花费多少钱。
思路:一道明显的DP,得出买每个铲子的最小花费,然后递推即可。买i个铲子花费的最小值就是(买j个铲子的花费+(买i个铲子的花费-(买j个铲子的花费+满减的花费))。
状态转移方程就是:DP[i]=min(DP[i],DP[j]+sum[i]-sum[j+mix[i-j]])
ACCode:
// luogu-judger-enable-o2
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define Pair pair<int,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
// register
const int MAXN=2e5+10;
const int INF32=0x3f3f3f3f;
const LL INF64=0x3f3f3f3f3f3f3f3f;
const int MOD=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);
int a[MAXN],b[MAXN];
int mix[MAXN],DP[MAXN];
int n,m,k;
int main(){
while(~scanf("%d%d%d",&n,&m,&k)){
clean(mix,0);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(int i=1;i<=n;++i) b[i]=b[i-1]+a[i];
for(int i=1;i<=m;++i){
int x,y;scanf("%d%d",&x,&y);
mix[x]=max(mix[x],y);
}
for(int i=1;i<=k;++i){
DP[i]=INF32;
for(int j=0;j<i;++j){
DP[i]=min(DP[i],DP[j]+b[i]-b[j+mix[i-j]]);
}
}printf("%d\n",DP[k]);
}
}
G. Minimum Possible LCM(最小LCM)
题目链接:https://codeforces.com/contest/1154/problem/G
题目大意:给出n个数,从中选择两个数,使其的LCM最小,输出最小的LCM。LCM:最小公倍数。
思路:首先用排除法,暴力肯定不行。查看题解:枚举所有的GCD,然后根据其GCD找出存在的两个数。得出LCM,刷新ans。
ACCode:
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define Pair pair<int,int>
#define M_P(a,b) make_pair(a,b)
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
// register
const int MAXN=1e6+10;
const int MAXM=1e7+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
int a[MAXN],Vis[MAXM];
int n;
int main(){
while(~scanf("%d",&n)){
clean(Vis,0);
ll ans=1e18;int ans1=0,ans2=0;
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
if(Vis[a[i]]&&ans>a[i]){
ans=a[i];ans1=Vis[a[i]];ans2=i;
}
if(Vis[a[i]]==0) Vis[a[i]]=i;
}
for(int i=1;i<MAXM;++i){//GCD
if(i>ans) break;
int res1=0,res2=0;
for(int j=i;j<MAXM;j+=i){
if(Vis[j]==0) continue;
if(res1==0) res1=Vis[j];
else{
if(ans>1ll*a[res1]*j/i){
ans=1ll*a[res1]*j/i;
res2=Vis[j];
ans1=res1;ans2=res2;
}break;
}
}
}
if(ans1>ans2) swap(ans1,ans2);
printf("%d %d\n",ans1,ans2);
}
}