Codeforces Round #592 (Div. 2) A,B,C,D,E
题意思路:略
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int q,a,b,c,d,k; 6 cin>>q; 7 while(q--){ 8 cin>>a>>b>>c>>d>>k; 9 bool flag=false; 10 int ans1=0,ans2=0; 11 for (int i=1;i<=k;i++){ 12 if (i*c>=a&&(k-i)*d>=b){ 13 ans1=i; 14 ans2=(k-i); 15 flag=true; 16 break; 17 } 18 } 19 if (flag) 20 cout<<ans1<<" "<<ans2<<endl; 21 else 22 cout<<"-1"<<endl; 23 } 24 return 0; 25 }
题意:
旅馆存在两楼,每层楼的房间数都为n,0代表该房间门口无楼梯,1代表有楼梯
问小明从任意房间出发,一个房间只能路过一次,求可以路过房间的数量 的最大值
思路:
1.从第一层最左端点出发,找离的最远的楼梯上去,再返会到第二层最左端 路过的房间数记录下来
2.从第一层最右端点出发,找离的最远的楼梯上去,再返回到第二层最右端 路过的房间数记录下来
上述两者取最大值输出即可。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 #include<bits/stdc++.h> 5 using namespace std; 6 char str[1010]; 7 bool vis[5][1010]; 8 int main() 9 { 10 int q,n; 11 cin>>q; 12 while (q--){ 13 cin>>n>>str+1; 14 int tmp=-1,ans=n; 15 for (int i=1;i<=n;i++){ 16 if (str[i]=='1'){ 17 tmp=i; 18 break; 19 } 20 } 21 if (tmp!=-1) 22 ans=max(ans,(n-tmp+1)*2); 23 for (int i=n;i>=1;i--){ 24 if (str[i]=='1'){ 25 tmp=i; 26 break; 27 } 28 } 29 if (tmp!=-1) 30 ans=max(ans,(tmp*2)); 31 cout<<ans<<endl; 32 } 33 return 0; 34 }
题意:
已知整数 n,p,w,d
其中 n是游戏总局数,p是总得分,赢了得w分,平局得d分
求 x,y,z值, 分别为赢的局数,平的局数,输的局数
显然满足以下方程
x*w+y*d=p
x+y+z=n
若存在xyz,则输出x,y,z值,不存在则输出-1
思路:
先看一下数据范围 d (1≤n≤1e12,0≤p≤1e17,1≤d<w≤1e5),如果用线性的算法的话,只能围绕d和w。
x*w+y*d=p 变形------> x= (p-d*y)%w ,然后根据取余规律,x的范围在【0,w-1】,即【0,1e5-1】;然后直接暴力了。
1 #include<iostream> 2 typedef long long ll; 3 using namespace std; 4 int main() 5 { 6 ll n,p,w,d,x,y,z; 7 cin>>n>>p>>w>>d; 8 bool flag=false; 9 for (int i=0;i<w;i++){ 10 if ((p-(d*i))%w==0&&(p-(d*i))/w+i<=n&&p>=d*i){ 11 x=(p-(d*i))/w; 12 y=i; 13 z=n-x-y; 14 flag=true;break; 15 } 16 } 17 if (flag){ 18 cout<<x<<" "<<y<<" "<<z<<endl; 19 } 20 else 21 cout<<-1<<endl; 22 return 0; 23 }
题意:
有三种颜色,要给n个点进行涂色,不同结点涂不同颜色,具有不同花费,问在任意连续的直接相连的三个结点之间不存在同种颜色的情况下,求最小花费
思路:
从入度为1的点出发(如果存在入度大于2的点,就直接输出-1),然后分六种情况,
分别是12,13,21,23,31,32 (23的意思是第一个结点涂颜色2,二块涂颜色3,后面如果不想连续三个结点之间重复颜色的点,必定是231循环涂色)
六种情况取涂色花费最小值即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long int ll; 4 ll a[4][100004]; 5 vector <ll> v[100004]; 6 ll t[6][3]={{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}}; 7 ll ans[6]; 8 ll lans[6][100004]; 9 void dfs (ll i,ll j,ll k,ll count){ 10 ll temp=count%3; 11 ans[k]+=a[t[k][temp]][i]; 12 lans[k][i]=t[k][temp]; 13 for (ll m=0;m<v[i].size();m++) 14 { 15 if (v[i][m]!=j) 16 { 17 dfs(v[i][m],i,k,count+1); 18 } 19 } 20 } 21 int main(){ 22 ll n; 23 cin>>n; 24 memset(ans,0,sizeof(ans)); 25 for (ll i=1;i<=3;i++){ 26 for (ll j=1;j<=n;j++){ 27 cin>>a[i][j]; 28 } 29 } 30 for (ll i=0;i<n-1;i++) 31 { 32 ll c,d; 33 cin>>c>>d; 34 v[c].push_back(d); 35 v[d].push_back(c); 36 } 37 ll leaf; 38 for (ll i=1;i<=n;i++) 39 { 40 if (v[i].size()>2) 41 { 42 cout<<-1; 43 exit(0); 44 } 45 if (v[i].size()==1) 46 leaf=i; 47 } 48 ll ans_min=1e18; 49 ll ind; 50 for (ll i=0;i<6;i++) 51 { 52 dfs(leaf,-1,i,0); 53 // cout<<ans[i]<<" "; 54 if (ans[i]<ans_min) 55 { 56 ans_min=ans[i]; 57 ind=i; 58 } 59 } 60 cout<<ans[ind]<<endl; 61 for (ll i=1;i<=n;i++) 62 cout<<lans[ind][i]<<" "; 63 }
题意:
给你n个数,最多k次操作(操作次数可以小于k),每次操作只能让一个数+1或者-1,问 该数组的最大值 - 该数组的最小值 最小为多少
思路:
先排序一下,然后只需要对最小值进行+1,最大值进行-1。
问题只需要解决什么时候进行+1,什么时候进行-1。
只需要看最小值的数量和最大值的数量谁更少,若最小值的数量少,则所以最小值+1,反之最大值-1。(其实就是看谁的操作次数少能让max-min的值可以改变)
1 #include<iostream> 2 #include<bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 6 const int MAXN=1e5+10; 7 struct Node{ 8 ll a,cnt; 9 }mp[MAXN],bt[MAXN]; 10 bool cmp(const Node&a,const Node&b){ 11 if (a.a!=b.a) 12 return a.a<b.a; 13 } 14 ll n,k; 15 int main(){ 16 scanf("%lld%lld",&n,&k); 17 for (int i=1;i<=n;i++){ 18 scanf("%lld",&mp[i].a); 19 mp[i].cnt=0; 20 } 21 sort(mp+1,mp+n+1,cmp); 22 ll L=1,R=1,tmp=1; 23 for (int i=2;i<=n;i++){ 24 if (mp[i].a==mp[i-1].a){ 25 tmp++; 26 } 27 else if (mp[i].a!=mp[i-1].a){ 28 bt[R].cnt=tmp; 29 bt[R].a=mp[i-1].a; 30 R++; 31 tmp=1; 32 } 33 if (i==n){ 34 bt[R].cnt=tmp; 35 bt[R].a=mp[i].a; 36 } 37 } 38 ll ans=bt[R].a-bt[L].a; 39 // cout<<ans<<endl; 40 while(k>0&&L<R){ 41 if (bt[L].cnt>bt[R].cnt){ 42 if (k<bt[R].cnt) 43 break; 44 if (k>=bt[R].cnt*(bt[R].a-bt[R-1].a)){ 45 k-=bt[R].cnt*(bt[R].a-bt[R-1].a); 46 R--; 47 bt[R].cnt+=bt[R+1].cnt; 48 ans=min(ans,bt[R].a-bt[L].a); 49 } 50 else{ 51 ll tmp=k/bt[R].cnt; 52 k-=bt[R].cnt*tmp; 53 bt[R].a-=tmp; 54 ans=min(ans,bt[R].a-bt[L].a); 55 } 56 } 57 else{ 58 if (k<bt[L].cnt) 59 break; 60 if (k>=bt[L].cnt*(bt[L+1].a-bt[L].a)){ 61 k-=bt[L].cnt*(bt[L+1].a-bt[L].a); 62 L++; 63 bt[L].cnt+=bt[L-1].cnt; 64 ans=min(ans,bt[R].a-bt[L].a); 65 } 66 else{ 67 ll tmp=k/bt[L].cnt; 68 k-=tmp*bt[L].cnt; 69 bt[L].a+=tmp; 70 ans=min(ans,bt[R].a-bt[L].a); 71 } 72 } 73 } 74 cout<<ans<<endl; 75 return 0; 76 }