超算第一场周赛题解

1,比较简单的号码校验

根据题意来就是了,但可能对于新手来说不知道怎么将字符数字化为可以加减乘除的类型,比如int。

一些细节之处我放在代码里了

代码

#include <bits/stdc++.h>
using namespace std;
#define accelerate ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl "\n";
#define mod 11
#define ll long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f
const int N=1e5+10;
int main(){
    accelerate;//这是加快输入输出,这里加不加无所谓,数据不大
    string ss;//可以根据字符串大小变长的容器,可以用字符数组代替
    int s=0,opt=1;//s是总和,opt是要乘的数
    cin>>ss;//输入
    s+=(ss[0]-'0')*(opt++);//ss[0]-'0'就是上面说的转化过程,这里opt++就可以自动增加需要乘的数,++在后是先乘再自身增加。
    for(int i=2;i<=4;i++){
        s+=(ss[i]-'0')*(opt++);
    }
    for(int i=6;i<=10;i++){
        s+=(ss[i]-'0')*(opt++);
    }
    s=s%mod;//取模,模数在上面写着
    //下面就是分情况讨论了
    //substr是个函数,剪切ss中[a,a+b)之间的字符,然后返回该字符串
    if(s==10&&ss[12]=='X'){
        cout<<"Right";
    }
    else if(s==10&&ss[12]!='X'){
        cout<<ss.substr(0,12)<<"X";
    }
    else if(s==(ss[12]-'0')){
        cout<<"Right";
    }
    else cout<<ss.substr(0,12)<<s;
    return 0;
}

2,有点难度的挨个退出

这题就是著名的约瑟夫问题,非常经典。

思路:首先我们需要将全部的人都加入到一个队列中,然后还需要一个计数器来数当前是第几个,那么如果当前是第m个,那就出队,否则就将队首重新加入到队尾。整个思路就是模拟数人的过程。

#include <bits/stdc++.h>
using namespace std;
queue<int>q;
int main(){
    int x=1,n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) q.push(i);//所有人入队
    while(!q.empty()){//队中空了就结束循环
        if(x==m){//数到了第m个时
            cout<<q.front()<<" ";//输出
            q.pop();//出队
            x=1;//重置计时器
        }
        else{//否则重新入队,计时器加一
            x++;
            q.push(q.front());
            q.pop();
        }
    }
    return 0;
}

3, 比较困难的寻找卢本伟

思路1:还是模拟比赛的过程。两队两队地比,分高就重新入队,分低就出队。重复这个操作直到剩下两队,然会选择战力小的一队即可。由于需要输出编号,那么可以开一个结构体去打包编号和战力。

#include <bits/stdc++.h>
using namespace std;
#define accelerate ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl "\n";
#define mod 11
#define ll long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f
const int N=1e6+10;
struct pre{//结构体
    int num,zl;//编号和战力
}a;
queue<pre>q;//存结构体的队列
int main(){
    accelerate;
    int n;
    cin>>n;
    for(int i=1,len=pow(2,n);i<=len;i++){//储存
        a.num=i;
        cin>>a.zl;
        q.push(a);
    }
    int x=0,y=0,minn=0,xx,yy;
    while(q.size()!=2){//剩下两队就结束
        x=q.front().zl;
        xx=q.front().num;
        q.pop();
        y=q.front().zl;
        yy=q.front().num;
        q.pop();//前面就是取队首的前两个战队
        if(x>y) q.push(pre{xx,x});//比较前两队,选择战力高的留下
        else q.push(pre{yy,y});
    }
    x=q.front().zl;
    xx=q.front().num;
    q.pop();
    y=q.front().zl;
    yy=q.front().num;
    q.pop();
    if(x<y) cout<<xx;//输出战力低的一组
    else cout<<yy;
    return 0;
}

思路2:其实我们分析一下就可以知道如果将整个队伍分成两半,那么卢本伟和冠军那一组必定分别在前一半或者后一半战队中且战力最高,那么直接将整个队伍分成两半排序,分别取出在队伍两半中分别战力最高的两组,然后就知道卢本伟的战力了,然会去找编号即可,其实也可以直接存结构体,对结构体排序,就不用回去找编号了。这里数组小倒是没问题(主要是当时没想到)。

#include <bits/stdc++.h>
using namespace std;
#define accelerate ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl "\n";
#define mod 11
#define ll long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f
const int N=1e6+10;
int a[N];//储存后用于排序
int b[N];//备份用于寻找编号
int main(){
    int n;
    cin>>n;
    int mm=pow(2,n);//总的队伍数
    for(int i=1,len=pow(2,n);i<=len;i++){
        cin>>a[i];
        b[i]=a[i];
    }
    sort(a+1,a+mm/2+1);//排序
    sort(a+mm/2+1,a+mm+1);//排序
    int tt=min(a[mm/2],a[mm]);//取最小的战力
    for(int i=1;i<=mm;i++){//找编号
        if(b[i]==tt){
            cout<<i;
            break;
        }
    }
    return 0;
}

经验之谈

超算的话现在还没接触太深,就拿我在ACM实验室的经历来说吧。

当初呢我在以最后几名加入ACM之时,我就感觉到竞争十分的巨大,我于是在第一周就开始刷题,在实验室刷题,回寝室也还在刷。然而第一周的周赛和第二周的周赛我还是排名在后。但我相信,我的努力不会白费,当时我没有想过放弃或是摆烂,选择了那就一直走下去吧,后来时间证明我会是对的。在这我还是建议如果你选择好了这条路,那么就义无反顾的走下去吧,不要因一时的挫折而放弃,胜利永远属于你的。建议刷题和看看一些网上的博客,比如在csdn上有许多好的博客,那就说到这,拜拜。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值