Codeforces Round #514 (Div. 2)
A了兩道題,第三題沒看懂,第五題沒看完,第四題還沒來得及看。?
Codeforces Round #514 (Div. 2)
A. Cashier?
#include<iostream> #include<cstdio> using namespace std;int main(){int n,L,a,pre=0,t,l;int cnt=0;scanf("%d%d%d",&n,&L,&a);while(n--){scanf("%d%d",&t,&l);cnt+=(t-pre)/a;pre=t+l;}cnt+=(L-pre)/a;printf("%d\n",cnt);return 0; }?
B. Forgery?
姑且就把這題理解成蓋印章,問印章能否印出下面的圖案?枚舉中心點,判斷其合理性。合理的話給八個方向的'#'做上標記,說明能夠蓋出這8個'#'。最后枚舉所有的'#',看這些’#‘是否都能蓋出。
#include<iostream> #include<cstdio> #include<cstring> using namespace std;const int maxn=1010; char mp[maxn][maxn]; bool flag[maxn][maxn]; int dir[8][2]={-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1}; int n,m;bool check(int x,int y){ //枚舉可能是中心點的點,判斷這個點是中心點是否合理for(int i=0;i<8;i++){int fx=x+dir[i][0],fy=y+dir[i][1];if(mp[fx][fy]=='.') return false;}return true; }void change(int x,int y){ //合理的話,修改周邊'#'的標記,說明這個'#'能被寫出for(int i=0;i<8;i++){int fx=x+dir[i][0],fy=y+dir[i][1];flag[fx][fy]=true;} }bool work(){ //枚舉所有點,如果有'#'沒被寫出,說明這個圖形不合法,不能偽造出來for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(mp[i][j]=='#'&&!flag[i][j]) return false;}}return true; }int main(){scanf("%d%d",&n,&m);for(int i=0;i<n;i++)scanf("%s",mp[i]);memset(flag,0,sizeof(flag));for(int i=1;i<n-1;i++){for(int j=1;j<m-1;j++){if(check(i,j)) change(i,j);}}if(work()) puts("YES");else puts("NO");return 0; }?
?C. Sequence Transformation
題目大意:給你一個集合A,元素是1-n,找出集合A中所有元素的最大公約數(shù)x。將x放進集合B中,從集合A中移除一個元素(這個元素是任意的);繼續(xù)重復(fù)這個過程,直到集合A為空。輸出依次放入集合B的這n個數(shù)——輸出序列。問輸出序列字典序的最大值。也就是如何移除數(shù),才能使得最大公約數(shù)增大?
題解:盡快得使最大公約數(shù)增大,也就是消去1,3,5,7,9……(還剩2,4,6,8,10……)這時最大公約數(shù)為2
消去2,6,10……(還剩4,8……) 這時最大公約數(shù)為4
每次都是從剩下的序列中隔一個消一個,如果序列還剩三個數(shù)的話,肯定能提取成t*(1,2,3)這種形式---->t*(1,1,3).
1.遞推寫法
#include<iostream> #include<cstdio> using namespace std;int main() {int n;scanf("%d",&n);int res=1,cnt=n,len;for(int i=0;(1<<i)<=n;i++) {if (cnt==3){printf("%d %d %d",res,res,res*3);break;} len=(cnt+1)/2;//cout<<"A***len="<<len<<endl;for(int j=1; j<=len; j++) {printf("%d ",res);}cnt-=len;res*=2;}return 0; }2.遞歸寫法?
#include<iostream> #include<cstdio> #include<cstring> using namespace std;void func(int s, int t) {if(s==0) return;if(s==3){printf("%d %d %d",t,t,3*t);return;}int cnt = 0;for(int i=1;i<=s;i+=2) cnt++,printf("%d ",t);func(s-cnt,t*2); }int main(){int a;scanf("%d",&a);func(a,1);return 0; }?
D. Nature Reserve?
題解:long double 的范圍要比double的廣,因此使用long double 精度要更高些。
一些常用數(shù)據(jù)類型的長度入下
涉及的代碼:
#include<iostream> #include<cstdio> using namespace std; int main(){long double a;double b;long long c;long d;unsigned long long e;int f;cout<<"long double 占"<<sizeof(a)<<"個字節(jié)"<<endl;cout<<"double 占"<<sizeof(b)<<"個字節(jié)"<<endl;cout<<"long long 占"<<sizeof(c)<<"個字節(jié)"<<endl;cout<<"long 占"<<sizeof(d)<<"個字節(jié)"<<endl;cout<<"unsigned long long占"<<sizeof(e)<<"個字節(jié)"<<endl;cout<<"int 占"<<sizeof(f)<<"個字節(jié)"<<endl;return 0; }?
?
?E. Split the Tree
題解:有一個以1為根節(jié)點的樹,問你將樹至少分成幾部分,才能使得每部分的節(jié)點個數(shù)不超過L個,并且權(quán)值之和不超過S?(每部分都是一條路徑,后一節(jié)點是前個節(jié)點的父親,A vertical path is a sequence of vertices?v1,v2,…,vk where?vi (i≥2) is the parent of vi?1.)
我的做法就是自下向上找父親,如果滿足這條路徑上節(jié)點不超過L個,權(quán)值之和不超過S,繼續(xù)往上找。知道找到不滿足條件的,它可能需要開辟一條新的路徑。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e5+10; ll w[maxn]; ll fa[maxn]; bool flag[maxn];int main(){ll n,L;ll S;scanf("%lld%lld%lld",&n,&L,&S);bool tag=true;for(ll i=1;i<=n;i++){scanf("%lld",&w[i]);if(w[i]>S) tag=false;}for(ll i=2;i<=n;i++){scanf("%lld",&fa[i]);}if(!tag){printf("-1\n");return 0;}ll ans=0,tl,ts,tmp;for(ll i=n;i>=1;i--){if(!flag[i]){ans++;tl=L;ts=S;tmp=i;while(ts>=w[tmp]&&tl&&tmp){tl--;ts=ts-w[tmp];flag[tmp]=true;tmp=fa[tmp];}}}printf("%lld\n",ans);return 0; }?
總結(jié)
以上是生活随笔為你收集整理的Codeforces Round #514 (Div. 2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 两台linux 机器互联,Red Hat
- 下一篇: 生日倒计时代码