BUAAOJ 132~134 136~139 2015级C++第七次练习赛

15 篇文章 1 订阅
9 篇文章 1 订阅

132 - A - 胡乱走的和尚

题意:
对于这样一个矩阵,和尚从1出发,经过一系列上下左右乱走问最后在哪,如果走出去就完蛋啦。

123nn+1n+2n+3n+n2n+12n+22n+32n+n............(n1)n+1(n1)n+2(n1)n+3(n1)n+n 1 n + 1 2 n + 1 . . . ( n − 1 ) n + 1 2 n + 2 2 n + 2 . . . ( n − 1 ) n + 2 3 n + 3 2 n + 3 . . . ( n − 1 ) n + 3 ⋮ ⋮ ⋮ ⋱ ⋮ n n + n 2 n + n . . . ( n − 1 ) n + n

模拟一下就好啦,左右差n,上下差1。如果和尚走出去了直接break出来

#include <cstdio>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
int dic[205][2]={0};

//小和尚往哪走(LRDU)
char o[5];
int main(){

    //向量
    dic['D'][1]=dic['R'][0]=1;dic['U'][1]=dic['L'][0]=-1;

    //t:case总数
    //n,M:题目给出
    //x,y:当前坐标
    //oo:小和尚这次走了几步
    //flag:小和尚完蛋了吗?
    int t,n,M,x,y,oo,flag=1;
    for(scanf("%d",&t);t--;flag=1){
        scanf("%d%d",&n,&M);
        x=y=1;
        F(m,M){
            scanf("%s%d",o,&oo);
            if(flag){
                x+=dic[o[0]][0]*oo;y+=dic[o[0]][1]*oo;
                if(x<1||y<1||x>n||y>n)flag=0;
            }
        }
        if(flag)printf("%d\n",x*n+y-n);
        else puts("WanQuanGaoBuDong!");
    }
}

137 - B - NeXT

求比给定字符串大的字符串中最小的字符串。
设字符串 S=c1c2...cncn+1 S = c 1 c 2 . . . c n c n + 1 其中 cn+1=0 c n + 1 = ‘ ∖ 0 ′
我们知道靠前的字符要尽可能地小,那么从后往前找,第一个非降序字符就是我们需要完成交换的目标字符 ci c i (若未找到则 i=0 i = 0 跃出字符串下标)。
再次从后往前找,找到第一个大于 ci c i 的字符 cj c j
然后把 ci c i cj c j 交换,输出 c1...ci1cjcn...cj+1cicj1...ci+1 c 1 . . . c i − 1 c j c n . . . c j + 1 c i c j − 1 . . . c i + 1
易证明这个字符串一定是满足题意的字符串。
证明:
c1...ci1 c 1 . . . c i − 1 是相同前缀,无法增加,那么只考虑之后的字符串。 cj c j 是后续字符串中大于c_i中最小的字符。那么 c1...ci1cj c 1 . . . c i − 1 c j 是大于 c1...ci1ci c 1 . . . c i − 1 c i 最小的字符串,现在只用输出之后的字符串最小字典序即可。我们知道由于我们的算法后续字符串恰好是最大字典序,那么逆序输出即可。

#include <iostream>
#include <string>
using namespace std;
string str;
int main(){
    ios::sync_with_stdio(false);
    int len,cur,cur2,t;
    while(cin>>str){
        len=str.size();

        cur=len-2;
        while(cur>=0&&str[cur]>=str[cur+1])cur--;

        if(cur==-1)cout<<"What?"<<endl;
        else{
            cur2=len-1;
            while(cur2>cur&&str[cur2]<=str[cur])cur2--;
            t=str[cur];str[cur]=str[cur2];str[cur2]=t;

            for(int i=0;i<=cur;i++)cout<<str[i];
            for(int i=len-1;i>cur;i--)cout<<str[i];
            cout<<endl;
        }
    }
}

133 - C - 蛇形填数

题意:
观察

1,23,4 1 , 2 3 , 4
1,2,36,5,47,8,9 1 , 2 , 3 6 , 5 , 4 7 , 8 , 9
输出对应 n n 阶矩阵。
分奇偶行填数就行了,这个蛇形填数比书上的简单多了=w =

#include <cstdio>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
int main(){
    int n,cnt;
    while(~scanf("%d",&n)){
        cnt=0;
        F(i,n){
            if(i&1){
                cnt+=n;
                F(i,n)printf("%4d",cnt--);
                cnt+=n;
            }
            else F(i,n)printf("%4d",++cnt);
            puts("");
        }
        puts("");
    }
}

136 - D - 满天繁星

给定一组坐标(x,y,z),给定一组查询求对应(x,y,z)是否存在。

因为x,y,z[50,50],我们把x,y,z右偏50,然后*128(实际上64就足够了)得到哈希值,然后就很容易了。

hash(x,y,z)=((((x+50)<<7)+y+50)<<7)+z+50 h a s h ( x , y , z ) = ( ( ( ( x + 50 ) << 7 ) + y + 50 ) << 7 ) + z + 50

#include <cstdio>
#include <map>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
using namespace std;

//map构造的hash表
map<int,bool> hoshi;
int main(){
    int n,x,y,z;
    while(~scanf("%d",&n)){
        hoshi.clear();
        F(i,n){
            scanf("%d%d%d",&x,&y,&z);
            //不知道为什么hash内联以后会报错,干脆直接复制粘贴到对应地方算了。
            hoshi[((((x+50)<<7)+y+50)<<7)+z+50]=1;
        }
        scanf("%d",&n);
        F(i,n){
            scanf("%d%d%d",&x,&y,&z);
            puts(hoshi[((((x+50)<<7)+y+50)<<7)+z+50]?"YES":"NO");
        }
    }
}

139 - E - Easy Triangle

题意:求n阶杨辉三角

递推方程:

f[i][j]=f[i1][j]+f[i1][j1] f [ i ] [ j ] = f [ i − 1 ] [ j ] + f [ i − 1 ] [ j − 1 ]

#include <cstdio>

//杨辉三角C(n-1,m-1)
long long c[51][51]={0};
int main(){

    //直接求出50阶杨辉三角
    c[1][1]=1;
    for(int i=2;i<=50;i++)for(int j=1;j<=i;j++)c[i][j]=c[i-1][j]+c[i-1][j-1];

    int n;
    while(~scanf("%d",&n)){
        for(int i=0;++i<=n;printf("%d\n",c[i][i]))for(int j=1;j<i;j++)printf("%lld ",c[i][j]);
    }
}

138 - F - Water

题意:n个人等待接水,问n个人等待的时间最小是多少。

sort(A) s o r t ( A ) 后, ans=n1Si=n1i1Aj a n s = ∑ 1 n S i = ∑ 1 n ∑ 1 i A j ,因为根据排序不等式 Si S i 是对应长度 i i <script type="math/tex" id="MathJax-Element-3317">i</script>最小的序列和。

#include <cstdio>
#include <algorithm>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
using namespace std;
int a[10005];
int main(){
    int n;long long ans,s;
    while(~scanf("%d",&n)){
        ans=s=0;
        F(i,n)scanf("%d",&a[i]);
        sort(a,a+n);
        F(i,n){
            s+=a[i];
            ans+=s;
        }
        printf("%lld\n",ans);
    }
}

134 - G - Chem Is A Third Try!!

给你首先给你n个数组长度,然后接下来n行,每行为对应长度的数组,有M次操作,每次操作交换a和b两行数组,求最终数组序列。

由于行内数据不会进行交换,我们把每行看作一个字符串,然后就简单很多了!

#include <iostream>
#include <cstdio>
#include <string>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
using namespace std;
//行下标
int sorti[1005];
//行数组
string s[1005];
int main(){
    ios::sync_with_stdio(false);
    int n,M,t,a,b;
    while(cin>>n>>M){
        //get掉n,M后面的\n
        getline(cin,s[0]);

        //s[0]是长度那一行
        FF(i,0,n)getline(cin,s[i]);
        FF(i,1,n)sorti[i]=i;
        F(m,M){
            cin>>a>>b;
            t=sorti[a];sorti[a]=sorti[b];sorti[b]=t;
        }
        FF(i,1,n)cout<<s[sorti[i]]<<endl;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值