10.26周赛补题

http://101.76.200.10/cache/4/03/maratona.ime.usp.br/7e08452c5de83ec599229759a9466aca/maratona_en.pdf

A.问能否从左上角走到右下角,那么就转化为能否从左下角走到右上角,如果能走到,则原来的路线不通,类似于狼抓兔子

#include
#include
#include
#include
#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<
            }
    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<
        }
        if(n-a[i]<=c[i]){//under
            Insert(i,k+n+b[i]);
            Insert(k+n+b[i],i);
//            cout<
        }
        if(m-b[i]<=c[i]){//right
            Insert(i,k+m+n+a[i]);
            Insert(k+m+n+a[i],i);
//            cout<
        }
        if(a[i]-1<=c[i]){//on
            Insert(i,k+m+n+n+b[i]);
            Insert(k+m+n+n+b[i],i);
//            cout<
        }
    }
    nn=(n+m)*2+k+1;
    for(int i=k+2;i){
        Insert(0,i);
        Insert(i,0);
    }
    for(int i=k+m+n+1+1;i){
        Insert(i,nn);
        Insert(nn,i);
    }
    bool flag=bfs();
    if(flag)puts("N");
    else puts("S");
    return 0;
}
View Code

B.水题

#include
#include
#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;
}
View Code

D.巧妙地运用了数链剖分轻重链的思想,不同点是这里的重链定义为从该点出发的最长链

#include
#include
#include
#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]]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<
    for(int i=1;i<=n;i++){
        if(leave[i]){
            sz[++cnt]=dep[i]-dep[top[i]]+1;
//            cout<
        }
    }
    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;
}
View Code

H.水题,但是要手写ceil函数,否则过不了

#include
#include
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;
}
View Code

 

I.二分答案

#include
#include
#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;
}
View Code

 

你可能感兴趣的:(10.26周赛补题)