Educational Codeforces Round 77 (Rated for Div. 2)node
A. Heatingios
題意:n組數據,每組數據告訴你有ci個數,他們的和爲sumi,求他們平方的和最小是多少。c++
思路:對於每組數據讓ci個數儘量的相等。(均值不等式可推)算法
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); long long n; cin>>n; while(n--){ long long c,sum; cin>>c>>sum; long long small_num=sum/c,big_num,ans=0; if(sum%c==0){ ans=small_num*small_num*c; }else{ big_num=small_num+1; long long cont_big=sum%c; long long cont_small=c-cont_big; ans=big_num*big_num*cont_big+small_num*small_num*cont_small; } cout<<ans<<endl; } return 0; }
題意:t組數據,每組數據有兩個數a和b,如今有兩種操做,①:a=a-x,b=b-2x ②:a=a-2x,b=b-x 每次能夠其一進行操做,x可取任意正整數,問可否將a和b同時變爲0。spa
思路:先取a爲較小數,b爲較大數,分類討論。若b爲a的2倍,則能夠;若b大於a的2倍,則不能夠;若a≤b<2a,考慮先將2個數變得相等(a減去1倍b和a的差,b減去2倍b和a的差),若這個數是3的倍數則能夠同時減爲0。(相等後分別a-2x,b-x再a-x,b-2x)。3d
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int n; cin>>n; while(n--){ long long a,b,num1,num2,cha,sheng; cin>>num1>>num2; a=min(num1,num2);b=max(num1,num2); cha=b-a; bool flag; if(cha==a){ flag=true; }else if(cha>a){ flag=false; }else{ sheng=a-cha; if(sheng%3==0){ flag=true; }else{ flag=false; } } if(flag) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
題意:你給柵欄塗色,柵欄標號0、一、2……10100,r倍數的柵欄塗第一種顏色,b倍數的柵欄塗第二種顏色,a和b的公倍數能夠任選顏色塗,而後將全部塗色的柵欄取下來,按順序排在一塊兒,若是有k個連續的柵欄塗同一種顏色,你將被國王認爲是反叛者並處死,問你可否找出塗色方法讓你存活,輸出服從(就是有方法活着),或反叛者(沒有塗色方法能夠存活)。blog
思路:先將兩個數處以他們的gcd,保證2數互質或相等,取r爲較小數,b爲較大數。分類討論。①:若r等於1,則b-1要小於k才能存活,不然處死。②:若b%r≥2,則b對應的柵欄之間能夠放b/r+1個r顏色柵欄,而後對這個結果判斷是否小於k便可。例如(b=8,r=3的某一段):排序
(補充,2個數a和b互質,則必定存在k使得 (k×a)%b=t,t能夠爲小於b的任意值)。若是b%r<2,則b對應的柵欄之間能夠放b/r個r顏色柵欄,對這個結果判斷是否小於k便可。
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int t; long long r,b,k,num1,num2; cin>>t; while(t--){ cin>>num1>>num2>>k; r=min(num1,num2); b=max(num1,num2); long long gcd_num=__gcd(r,b); r/=gcd_num;b/=gcd_num; bool flag=true; if(r==1){ if(b>=k+1) flag=false; else flag=true; }else{ if(b%r>=2){ if(b/r+1>=k){ flag=false; }else{ flag=true; } }else{ if(b/r>=k){ flag=false; }else{ flag=true; } } } if(flag) cout<<"OBEY"<<endl; else cout<<"REBEL"<<endl; } return 0; }
題意:一個數軸,你從0出發要到n+1,你有m個士兵能夠選(每一個士兵有一個敏捷度),而後有k個陷阱和時間t。每一個陷阱有三個值l,r,d,l是陷阱位置 ,r是解除陷阱你須要去的位置,d是危險程度。士兵的敏捷度若小於d則士兵當即死亡。有以下幾種操做。
· 若是你在x,你能夠耗時1秒去到x-1或x+1
· 若是你和你的軍隊同時在x,你能夠耗時1秒帶着你的士兵去到x-1或x+1,若去到的地方有陷阱且會讓你的士兵被殺,則你不能這麼移動。
· 若是你到達了x,且x是解除陷阱的位置(x爲某個r),則x對應的陷阱當即解除,不耗費時間。
如今問在時間t內你最多能夠帶多少個士兵到達目的地。
思路:首先貪心的思想,你若帶K個士兵則必定是敏捷度最大的K個士兵,因此二分搜索士兵的個數,並判斷相應個數的士兵可否在時間t內到達。
對於可否到達,將陷阱按照l從小到大的順序排序,危險值小於等於當前選的K個士兵中敏捷度最小的陷阱能夠忽略。對於每一個陷阱,若拆除對應的最遠的r大於後面陷阱的位置l,則後面的陷阱與以前的陷阱一塊兒拆除,並更新最遠的r。若拆除對應的最遠r小於下一個陷阱l,則把以前選中的陷阱拆除後帶着部隊來到l-1.算法全部便可。
#include<bits/stdc++.h> using namespace std; map<int,int>tree; struct node{ int agility,num; }now_node; struct node_point{ int l,r,d; }now_point; vector<node>soldier; vector<node_point>point; bool judge(int x,int t,int aim){ int max_point=0,last_move=0,sum=0; for(int i=0;i<point.size();i++){ if(x>=point[i].d) continue; if(max_point>=point[i].l){ max_point=max(point[i].r,max_point); }else{ sum+=(max_point-last_move)*2+(point[i].l-1-last_move); max_point=point[i].r; last_move=point[i].l-1; } } sum+=(max_point-last_move)*2+(aim-last_move); if(sum<=t) return true; else return false; } int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int n,m,t,k,get_num; cin>>m>>n>>k>>t; for(int i=1;i<=m;i++){ cin>>get_num; if(tree.find(get_num)==tree.end()){ tree[get_num]=1; }else{ tree[get_num]++; } } for(auto i=tree.begin();i!=tree.end();i++){ now_node.agility=(*i).first; now_node.num=(*i).second; soldier.push_back(now_node); } for(int i=1;i<=k;i++){ cin>>now_point.l>>now_point.r>>now_point.d; point.push_back(now_point); } sort(point.begin(),point.end(),[](const node_point &a,const node_point &b){return a.l<b.l;}); int l=0,r=soldier.size(); while(l<r){ int mid=(l+r)/2; if(judge(soldier[mid].agility,t,n+1)){ r=mid; }else{ l=mid+1; } } int ans=0; if(l==soldier.size()){ cout<<ans<<endl; }else{ for(int i=l;i<soldier.size();i++){ ans+=soldier[i].num; } cout<<ans<<endl; } return 0; }