http://101.76.200.10/cache/4/03/maratona.ime.usp.br/7e08452c5de83ec599229759a9466aca/maratona_en.pdfnode
A.問可否從左上角走到右下角,那麼就轉化爲可否從左下角走到右上角,若是能走到,則原來的路線不通,相似於狼抓兔子ios
#include<iostream> #include<cstdio> #include<queue> #include<cmath> #define maxn 100010 using namespace std; int m,n,k,a[maxn],b[maxn],c[maxn],head[maxn],num,nn; bool vis[maxn]; struct node{ int to,pre; }e[maxn*50]; int Abs(int x){ if(x>0)return x; else return -x; } void Insert(int from,int to){ e[++num].to=to; e[num].pre=head[from]; head[from]=num; } queue<int>q; bool bfs(){ vis[0]=1; q.push(0); while(!q.empty()){ int now=q.front();q.pop(); for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(vis[to])continue; vis[to]=1; q.push(to); if(to==nn)return 1; } } if(vis[nn])return 1; return 0; } int main(){ scanf("%d%d%d",&n,&m,&k); m++,n++; for(int i=1;i<=k;i++){ scanf("%d%d%d",&a[i],&b[i],&c[i]); a[i]=a[i]+1; b[i]=b[i]+1; } for(int i=1;i<=k;i++) for(int j=i+1;j<=k;j++) if(sqrt(1.0*(a[i]-a[j])*(a[i]-a[j])+1.0*(b[i]-b[j])*(b[i]-b[j]))<=c[i]*1.0+c[j]*1.0){ Insert(i,j); Insert(j,i); // cout<<i<<' '<<j<<endl; } for(int i=1;i<=k;i++){ if(b[i]-1<=c[i]){//left Insert(i,k+a[i]); Insert(k+a[i],i); // cout<<i<<' '<<k+a[i]<<endl; } if(n-a[i]<=c[i]){//under Insert(i,k+n+b[i]); Insert(k+n+b[i],i); // cout<<i<<' '<<k+n+b[i]<<endl; } if(m-b[i]<=c[i]){//right Insert(i,k+m+n+a[i]); Insert(k+m+n+a[i],i); // cout<<i<<' '<<k+m+n+a[i]<<endl; } if(a[i]-1<=c[i]){//on Insert(i,k+m+n+n+b[i]); Insert(k+m+n+n+b[i],i); // cout<<i<<' '<<k+m+n+n+b[i]<<endl; } } nn=(n+m)*2+k+1; for(int i=k+2;i<k+m+n;i++){ Insert(0,i); Insert(i,0); } for(int i=k+m+n+1+1;i<k+m+n+m+n;i++){ Insert(i,nn); Insert(nn,i); } bool flag=bfs(); if(flag)puts("N"); else puts("S"); return 0; }
B.水題ide
#include<iostream> #include<cstdio> #define maxn 110 using namespace std; int n,T; char s[maxn]; int main(){ scanf("%d",&T); while(T--){ scanf("%d%s",&n,s+1); int l=-1,r=-1; for(int i=1;i<=n;i++){ if(s[i]=='>'&&l==-1)l=i; if(s[n-i+1]=='<'&&r==-1)r=i; } if(l==-1||r==-1)l=r=1; int ans=min(l,r); ans--; printf("%d\n",ans); } return 0; }
D.巧妙地運用了數鏈剖分輕重鏈的思想,不一樣點是這裏的重鏈定義爲從該點出發的最長鏈函數
#include<iostream> #include<cstdio> #include<algorithm> #define maxn 100010 using namespace std; int n,m,dep[maxn],fa[maxn],top[maxn],head[maxn],num,son[maxn],maxdep[maxn]; int cnt,sz[maxn]; bool leave[maxn]; struct node{ int to,pre; }e[maxn*2]; void Insert(int from,int to){ e[++num].to=to; e[num].pre=head[from]; head[from]=num; } bool cmp(int x,int y){return x>y;} void dfs1(int now,int father){ dep[now]=dep[father]+1; maxdep[now]=dep[now]; fa[now]=father; bool flag=0; for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(to==father)continue; dfs1(to,now); if(!son[now]||maxdep[son[now]]<maxdep[to])son[now]=to; maxdep[now]=max(maxdep[now],maxdep[to]); flag=1; } if(!flag)leave[now]=1; } void dfs2(int now,int father){ top[now]=father; for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(to==fa[now])continue; if(to==son[now])dfs2(to,father); else dfs2(to,to); } } int main(){ freopen("Cola.txt","r",stdin); scanf("%d%d",&n,&m); int x; for(int i=2;i<=n;i++){ scanf("%d",&x); Insert(x,i); Insert(i,x); } dfs1(1,1); dfs2(1,1); // for(int i=1;i<=n;i++)cout<<top[i]<<' ';cout<<endl; for(int i=1;i<=n;i++){ if(leave[i]){ sz[++cnt]=dep[i]-dep[top[i]]+1; // cout<<i<<' '<<sz[cnt]<<endl; } } sort(sz+1,sz+n+1,cmp); int ans=0; for(int i=1;i<=m;i++)ans+=sz[i]; printf("%d\n",ans); return 0; }
H.水題,可是要手寫ceil函數,不然過不了spa
#include<iostream> #include<cstdio> using namespace std; int n,m; int Ceil(double x){ return x+0.9999999; } int main(){ scanf("%d%d",&n,&m); int ans; for(double i=0.1;i<=0.9;i+=0.1){ ans=Ceil(i*n*m); printf("%d ",ans); } puts(""); return 0; }
I.二分答案code
#include<iostream> #include<cstdio> #define maxn 100010 using namespace std; int a[maxn],n,c,k,ans; bool Judge(int x,int limit){//ÅжÏÄÜ·ñÔÚlimitÃëÄÚ³ÔÍêx¸öÓñÃ× int flag=0; if(x%k)flag=1; return x/k+flag<=limit; } bool check(int x){//Åжϲ»³¬¹ý¸ÃÃëÊýÄÜ·ñ³ÔÍê int sum=0,cnt=0; for(int i=1;i<=n;i++){ if(Judge(sum+a[i],x)){ sum+=a[i]; } else { cnt++; sum=a[i]; } if(cnt>c)return 0; } if(cnt+1>c)return 0; return 1; } int main(){ scanf("%d%d%d",&n,&c,&k); for(int i=1;i<=n;i++)scanf("%d",&a[i]); int l=0,r=1000000000; for(int i=1;i<=n;i++){ int flag=0; if(a[i]%k)flag=1; l=max(l,flag+a[i]/k); } while(l<=r){//¶þ·ÖÃëÊý int mid=(l+r)>>1; if(check(mid))r=mid-1,ans=mid; else l=mid+1; } printf("%d\n",ans); return 0; }