ZUT第十届校赛



还没看题解,所以我写的可能不是最优解,欢迎各位来找我讨论。题目就不贴了…


A: zzq和飞行棋(签到题 * 1)

这个规则还是我告诉zzq的,结果WA了5次,枯辽…

#include<cstdio>
int n,x,y;

bool solve(){
    y%=((n-1)<<1);
    return x-1==y;
}

int main(){
    while(~scanf("%d%d%d",&n,&x,&y)){
        if(solve()) printf("handsome zzq!\n");
        else printf("how pity zzq!\n");
    }
    return  0;
}

B: syp和验证码(签到题 * 2)

#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
 
string a,b;
 
bool solve1(){
    int i,num1=0,num2=0,ans=0,num=0;
    for(i=0;i<a.length();++i){
        if(a[i]>='0'&&a[i]<='9') num1=num1*10+a[i]-'0';
        else break;
    }
    int tmp=i;
    for(int j=tmp+1;j<a.length();++j){
        if(a[j]>='0'&&a[j]<='9') num2=num2*10+a[j]-'0';
    }
    if(a[i]=='+')ans=num1+num2;
    else if(a[i]=='-')ans=num1-num2;
    else if(a[i]=='*')ans=num1*num2;
    else if(a[i]=='/')ans=num1+num2;
    for(int j=0;j<b.length();++j){
        if(b[j]>='0'&&b[j]<='9') num=num*10+b[j]-'0';
    }
    //printf("num1=%d,num2=%d,num=%d",num1,num2,num);
    return (ans==num);
}
 
bool solve2(){
    if(a.length()!=b.length())return false;
    for(int i=0;i<a.length();++i){
        if(a[i]>='a'&&a[i]<='z')a[i]-=32;
        if(b[i]>='a'&&b[i]<='z')b[i]-=32;
        //if(a[i]!=b[i]||a[i]-b[i]!=32||b[i]-a[i]!=32)return false;
        if(a[i]!=b[i])return false;
    }
    return true;
}
 
int main(){
    while(cin>>a>>b){
        bool ans=false;
        if((a[0]>='0'&&b[0]>='0'&&a[0]<='9'&&b[0]<='9')) ans=solve1();
        else ans=solve2();
        if(ans)printf("yeyeye!\n");
        else printf("kujiji!\n");
    }
     
    return  0;
}

C: syp和强迫症Ⅰ(二分)

看问法就是一题二分题,但这题不用二分也可以做。
二分找第一棵树的高度:

#include<cstdio>
#define ll long long
int n;
ll a[37];

bool judge(ll x){
    ll base=x;
    for(int i=0;i<n;++i){
        if(a[i]>base) return false;
        base<<=1;
    }
    return true;
}
 
int main(){
    int T;scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=0;i<n;++i)scanf("%lld",&a[i]);
        if(n==1){printf("0\n");continue;} 
        ll res=-1,l=a[0],r=1e9,mid,ans=0;
        while(l<=r){
            mid=(l+r)>>1;
            if(judge(mid)){
                r=mid-1;
                res=mid;
            }
            else l=mid+1;
        }
        if(res==-1){printf("-1\n");continue;}
        for(int i=0;i<n;++i){
            ans+=res-a[i];
            res<<=1;
        }
        printf("%lld\n",ans);
    }   
    return  0;
}

D: syp和强迫症Ⅱ(线段树)

线段树区间修改,维护区间最大值与区间和(板子题呀)。
我写了一晚上还是WA。过了再贴代码。//更新:又一次WA在long long

#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define max(a,b) ((a)>(b))?a:b
  
int a[100007],maxx[400007];
ll sum[400007],tag[400007];
 
void update(int node){
    maxx[node]=max(maxx[node<<1],maxx[node<<1|1]);
    sum[node]=sum[node<<1]+sum[node<<1|1];
}
 
void build(int l,int r,int node){
    if(l==r){
        maxx[node]=a[l-1];
        sum[node]=a[l-1];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,node<<1);
    build(mid+1,r,node<<1|1);
    update(node);
}
 
void down(int l,int r,int x){
    int mid=(l+r)>>1;
    if(tag[x]!=0){
        tag[x<<1]+=tag[x];
        tag[x<<1|1]+=tag[x];
        sum[x<<1]+=(mid-l+1)*tag[x];
        sum[x<<1|1]+=(r-mid)*tag[x];
        maxx[x<<1]+=tag[x];
        maxx[x<<1|1]+=tag[x];
        tag[x]=0;
    }
}
void add(int s,int t,int l,int r,int x,int v){
    if(s<=l&&r<=t){
        tag[x]+=v;
        maxx[x]+=1;
        sum[x]+=v*1ll*(r-l+1);
        return;
    }
    down(l,r,x);
    int mid=(l+r)>>1;
    if(s<=mid)add(s,t,l,mid,x<<1,v);
    if(mid<t)add(s,t,mid+1,r,x<<1|1,v);
    update(x);
}
int querymax(int l,int r,int node,int s,int t){
    if(s<=l&&r<=t)    return maxx[node];
    down(l,r,node);
    int mid=(l+r)>>1,ans1=0,ans2=0;
    if(s<=mid)   ans1=querymax(l,mid,node<<1,s,t);
    if(mid<t)    ans2=querymax(mid+1,r,node<<1|1,s,t);
    ans1=max(ans1,ans2);
    return ans1;
}
ll querysum(int l,int r,int node,int s,int t){
    if(s<=l&&r<=t)    return sum[node];
    down(l,r,node);
    int mid=(l+r)>>1;
    ll ans=0;
    if(s<=mid)   ans+=querysum(l,mid,node<<1,s,t);
    if(mid<t)    ans+=querysum(mid+1,r,node<<1|1,s,t);
    return ans;
}
/*
void debug(){
    printf("******************\n");
    for(int i=1;i<=7;++i){
        printf("%d ",sum[i]);
        if(i==3||i==7||i==1)printf("\n");
    }
    printf("\n");
    for(int i=1;i<=7;++i){
        printf("%d ",maxx[i]);
        if(i==3||i==7||i==1)printf("\n");
    }
    printf("\n*******************\n");
}*/
  
int main(){
    int n,T,s,t;scanf("%d%d",&n,&T);
    char op[10];
    for(int i=0;i<n;++i)scanf("%d",&a[i]);
    build(1,n,1);
    while(T--){
        scanf("%s",op);
        if(strcmp(op,"1")==0){
            scanf("%d%d",&s,&t);
            ll res=querymax(1,n,1,s,t);
            ll summ=querysum(1,n,1,s,t);
            //printf("res=%lld,summ=%lld\n",res,summ);
            ll ans=(t-s+1)*1ll*res-summ;
            printf("%lld\n",ans);
        }
        if(strcmp(op,"2")==0){
            scanf("%d%d",&s,&t);
            add(s,t,1,n,1,1);
            //debug();
        } 
    }
    return  0;
}

E: syp和强迫症Ⅲ(STL)

这么简单的题都没人写的嘛?

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
 
int a[500017];
queue<int> q;
  
int main(){
    int n;scanf("%d",&n);for(int i=0;i<n;++i)scanf("%d",&a[i]);
    sort(a,a+n);
    for(int i=0;i<n;++i)q.push(a[i]);
    int maxx=-1;
    long long ans=0;
    while(!q.empty()){
        int now=q.front();q.pop();
        if(now<=maxx){
            ans+=(long long)(maxx-now+1);
            maxx+=1;
        }
        else maxx=now;
    }
    printf("%lld\n",ans);
    
    return  0;
}

F: wzy和ly和怪兽(签到题 * 3)

斐波那契博弈。写过两遍了…
如果不知道,就现场瞎找规律,也可以发现的。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
long long a[100];
 
int main(){
    a[0]=a[1]=1;
    int i;
    for(i=2;i<=91;++i)a[i]=a[i-1]+a[i-2];	//这个 91 是我打表找出来的
    //printf("i=%d\n",i);
    long long x;
    while(~scanf("%lld",&x)){
        int r=lower_bound(a,a+i,x)-a;
        //printf("%lld a[%d]=%lld\n",x,r,a[r]);
        if(r!=i&&a[r]==x)printf("lynb!\n");
        else printf("wzynb!\n");
    } 
     
    return  0;
}

G: ly和旅游(最短路)

学长说我写的不对,我过了再贴。


H: wsw和字符串(DP)

简单dp。
注意开long long。

#include<cstdio>
#include<cstring>
using namespace std;
 
char a[117];
long long dp[117];
 
int getnum(char a,char b){
    return (a-'0')*10+(b-'0');
}
 
int main(){
    while(~scanf("%s",a)){
        memset(dp,0,sizeof(dp));
        dp[0]=dp[1]=1;
        int len=strlen(a);
        for(int i=1;i<len;++i){
            int num=getnum(a[i-1],a[i]);
            if(num>=10&&num<=25) dp[i+1]=dp[i-1]+dp[i];
            else dp[i+1]=dp[i];
        }
        printf("%lld\n",dp[len]);
    }
     
    return  0;
}

I: syp和ly和¥100(BFS)

就是个BFS。

#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
struct S{
    int x,y,step;
    S(){}	//原来要写这玩意昂,不然无法编译
    S(int xx,int yy,int zz):x(xx),y(yy),step(zz){}
    bool operator<(const S &a)const{
        return step>a.step;
    }
}endd,tt[90000];
char a[317][317];
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
 
 
int main(){
    int n,m;scanf("%d%d",&n,&m);for(int i=0;i<n;++i) scanf("%s",&a[i]);  
    priority_queue<S> q;
    int tail=0,ans=INF;
    for(int i=0;i<n;++i){
        for(int j=0;j<m;++j){
            if(a[i][j]=='T'){
                tt[tail].x=i,tt[tail].y=j,tt[tail].step=INF;
                tail++;
            }
            else if(a[i][j]=='E') endd.x=i,endd.y=j;
            else if(a[i][j]=='S'){
                a[i][j]='X';
                q.push(S(i,j,0));
            } 
        }
    }
    while(!q.empty()){
        S now=q.top();
        int nx=q.top().x,ny=q.top().y;q.pop();
        for(int i=0;i<4;++i){
            int x=nx+dx[i],y=ny+dy[i];
            if(endd.x==x&&endd.y==y){
                printf("%d\n",now.step+1);
                return  0;
            } 
            if(x>=0&&x<n&&y>=0&&y<m&&a[x][y]!='X'){
                if(a[x][y]=='T'){
                    for(int j=0;j<tail;++j){
                        if(tt[j].x!=x||tt[j].y!=y){
                            q.push(S(tt[j].x,tt[j].y,now.step+2));
                            a[tt[j].x][tt[j].y]=a[x][y]='X';
                        } 
                    } 
                } 
                a[x][y]='X';
                q.push(S(x,y,now.step+1));
            }
        }
    }
    printf("-1\n");
    return  0;
}

J: syp和鸽子(签到题 * 4)

好讨厌模拟题啊。
签到失败!!!


K: ly和难题(签到题 * 5)

#include<cstdio>
char a[500];
int main(){
    int n,x=0,y=0;scanf("%d%s",&n,&a);
    for(int i=0;i<n;++i){
        if(a[i]=='1') ++x;
        else ++y;
    }
    x>y?printf("Easy!\n"):printf("Hard!\n"); 
    return  0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值