Atcoder Beginner Contest 167

赛场实况:

 

训练反思: A题签到不说了,B题第一眼没看清楚数据范围,写了一堆然后仔细一看1e12果断不能暴力..立马换了一个写法,连交2发wa(细节啊细节!!),C题看了半天英语没看懂说了什么,拿翻译软件翻了一下才算是懂,小数据范围一眼看出dfs,然后一发过(英语好菜qaq),D也是个简单题,就是找循环节,但是一直RE(想了半小时没想懂为什么),最后仔细看了一下题发现可以自己指向自己.....那么一开始就是死循环1的情况,压哨AC...。EF等我有空了补一下再更新。

 

A:Registration

签到题没意思,不说了。

#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
int main(){
    string s,t;cin>>s>>t;
    if(t.length()==s.length()+1){
        int flag=0;
        for(int i=0;i<s.length();i++){
            if(s[i]!=t[i]){
                flag=1;break;
            }
        }
        if(flag) puts("No");
        else puts("Yes");
    }else{
        puts("No");
    }
}
View Code

 

B:Easy Linear Programming

签到题,依次贪心a,然后再贪心b,最后贪心c,注意数据范围,别无脑莽(比如我)

#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
int main(){
    ll a,b,c,k;cin>>a>>b>>c>>k;
    ll ans=0;
    if(k<=a){
        ans=k;cout<<ans<<endl;return 0;
    }
    else if(k>a&&k<=a+b){
        ans+=a;
        cout<<ans<<endl;return 0;
    }else if(k>(b+a)){
        ans+=a;
        ans-=(k-(a+b));
        cout<<ans<<endl;return 0;
    }
}
View Code

 

C:Skill Up

题意:n行,m列,然后每一行购买的代价是C[i],如果你购买了该i行,你m个技能每个技能经验+a[i][j],然后题目要求每个技能的经验严格>=x,问你最小购买的代价.

我不知道有什么简便做法,反正我看到n,m<=12就觉得是dfs,但是我看榜单过的速度好快...或许有更简单的做法吧。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int a[20][20],c[20],cur[20];int n,m,k,ans=INF;
void dfs(int x,int sum){
    for(int i=1;i<=m;i++){
        cur[i]+=a[x][i];
    }
    int fg=1;
    for(int i=1;i<=m;i++){
        if(cur[i]<k) fg=0;
    }
    if(fg==1) {ans=min(ans,sum+c[x]);}
    for(int i=x+1;i<=n;i++){
        dfs(i,sum+c[x]);
        for(int j=1;j<=m;j++){
            cur[j]-=a[i][j];
        }
    }
}
int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
        cin>>c[i];
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        mem(cur,0);
        dfs(i,0);
    }
    if(ans!=INF) cout<<ans<<endl;
    else cout<<-1<<endl;
}
View Code

 

D:Teleporter

题意:有N个点,每个点与to[i]有个单向边,问从1开始走(1是第0个点),第k个点是什么。

解法:就是找循环节,然后如果k在循环节开始之前,那无所谓直接硬钢,如果在循环节之内了,那你需要减去循环节之前的数目,然后对于循环节总数取模确定你在循环节里的哪个位置。坑点,一个点可以自己走向自己(我没注意那么多一开始,以为题目默认不能这样...否则你会有3个RE点,我调了半小时心态都崩了,菜是原罪)

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=4e6+5;
ll to[maxn],pos[maxn],vis[maxn],mp[maxn];
int main(){
    ll n,k;cin>>n>>k;    
    for(int i=1;i<=n;i++){
        cin>>to[i];
    }
    pos[1]=1;vis[1]=1;mp[1]=1;
    ll now=to[1],cnt=1,dis=0,l=0;
    while(!vis[now]){
        vis[now]=++cnt;
        mp[cnt]=now;
        now=to[now];
        if(vis[now]){
            dis=cnt+1-vis[now];
            l=vis[now];
        }
    }
    k=k+1;
    if(l==0){cout<<"1"<<endl;return 0;}
    if(k<l){
        cout<<mp[k]<<endl;
    }else{
        k=k-l;
        k%=dis;
        k+=l;
        cout<<mp[k]<<endl;
    }
}
View Code

 

E:Colorful Blocks(待补)

 

F:racket Sequencing(待补)

posted @ 2020-05-10 22:08  Anonytt  阅读(391)  评论(0编辑  收藏  举报