ACM/ICPC 2018亚洲区预选赛北京赛站网络赛

因为过两天就是CCPC的原因,所以我们队决定模拟一下现场,也就是三个人只能在一台电脑上敲代码,其他两台只能用于读题和看代码,发现确实比三台机子要困难很多。

就像今天一样,我和一个队友在找代码问题,然后另一位队友对另外一题有了思路,这个时候我们只能复制代码到另外一台机子上看,也就是说不能修改了,也就不知道某个地方改了后是不是就正确了。

这种团队的配合还是得多比赛才能练出来的。


80 Days

题意: n个点成环,初始值mo,走到一个点+ai(可能小于0),去下一个点-bi(大于0),任何时候值都不能小于0,求哪个点为起点时可能走完一圈

说来惭愧,就是一个for循环的事情,分要写成前缀和,还写错了。最后i=n+1写出i=i+1又WA了一发。。。

#include<stdio.h>
using namespace std;
#define LL long long

const int N=1e6+5;

LL ab[2*N],a[2*N];
LL mo;

int ans;


int main(){
    int t;scanf("%d",&t);
    while(t--){
        int n;scanf("%d%lld",&n,&mo);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(int i=1;i<=n;i++){
            LL tmp;
            scanf("%lld",&tmp);
            ab[i]=a[i]-tmp;
        }
        for(int i=n+1;i<=2*n;i++){
            a[i]=a[i-n];
            ab[i]=ab[i-n];
        }
        int l=1,r=1;
        LL now=mo+ab[1];

        while(now<0&&l<=n){
            l++,r++;
            now=mo+ab[l];
        }
        if(l==n+1){printf("-1\n");continue; }

        while(1){
            while(now>=0&&r<l+n-1){
                r++;
                now+=ab[r];
            }
            if(now>=0&&r==l+n-1){printf("%d\n",l);break;}
            while(now<0&&l<r){
                l++;
                now-=ab[l-1];
            }
            while(l==r&&now<0&&l<=n){
                now-=ab[l];
                l++,r++;
                now+=ab[l];
            }
            if(l>n){printf("-1\n");break; }
        }
    }
}

Saving Tang Monk II

队友写的直接上代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int n,m,k,dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
ll ans;
char mp[105][105];
struct Node
{
    int dis,x,y,num;
    Node(){}
    Node(int dis,int x,int y,int num) : dis(dis),x(x),y(y),num(num){}
    bool operator < (const Node& rhs) const{
        if(dis!=rhs.dis)
        return dis > rhs.dis;
        else return num>rhs.num;
      }
};
ll dis[105][105][8];
bool vis[105][105][8];
int ck(int x,int y){
    if(x<1||x>n||y<1||y>m) return 0;
    return 1;
}
void Dijkstra(int stx,int sty,int enx,int eny){
    priority_queue<Node> Q;
    while(!Q.empty()) Q.pop();
    Q.push(Node(0,stx,sty,0));
    dis[stx][sty][0]=0;
    while(!Q.empty()){
        Node u = Q.top(); Q.pop();
        if(vis[u.x][u.y][u.num]) continue;
        vis[u.x][u.y][u.num] = 1;
        //printf("x=%d y=%d dis=%d num=%d\n",u.x,u.y,u.dis,u.num);
        for(int i=0;i<4;i++){
            int dx=u.x+dir[i][0],dy=u.y+dir[i][1];
            if(!ck(dx,dy)) continue;
            if(mp[dx][dy]=='#'){
                if(u.num==0) continue;
                if(u.dis+2< dis[dx][dy][u.num-1]){
                    dis[dx][dy][u.num-1]=u.dis+2;
                    Q.push(Node(u.dis+2,dx,dy,u.num-1));
                }
            }
            if(mp[dx][dy]=='.'||mp[dx][dy]=='S'||mp[dx][dy]=='T'){
                if(u.dis+1< dis[dx][dy][u.num]){
                    dis[dx][dy][u.num]=u.dis+1;
                    Q.push(Node(u.dis+1,dx,dy,u.num));
                }
            }
            if(mp[dx][dy]=='P'){
                if(u.dis<dis[dx][dy][u.num]){
                    dis[dx][dy][u.num]=u.dis;
                    Q.push(Node(u.dis,dx,dy,u.num));
                }
            }
            if(mp[dx][dy]=='B'){
                if(u.dis+1<dis[dx][dy][u.num+1]){
                    dis[dx][dy][u.num+1]=u.dis+1;
                    Q.push(Node(u.dis+1,dx,dy,u.num+1));
                }
            }
        }
    }
}
int main(){
    //printf("%lld\n",INF);
    while(~scanf("%d%d",&n,&m)){
        if(n==0&&m==0) break;
        int stx,sty,enx,eny;
        for(int i=1;i<=n;i++){
            scanf("%s",mp[i]+1);
            for(int j=1;j<=m;j++){
                for(int k=0;k<=5;k++)
                    vis[i][j][k]=0,dis[i][j][k]=inf;
                if(mp[i][j]=='S')
                    stx=i,sty=j;
                if(mp[i][j]=='T')
                    enx=i,eny=j;
            }
        }
        ans=inf;
        Dijkstra(stx,sty,enx,eny);
        for(int i=0;i<=5;i++){
            ans=min(ans,dis[enx][eny][i]);
        }
        if(ans==inf) printf("-1\n");
        else  printf("%lld\n",ans);
    }
    return 0;
}

Tomb Raider

题意: 10个串每个串最长8,串在环上(可循环节:abc->bca->cab),问所有串的最长子序列

枚举最短串的所有子序列,然后用这个子序列去和其他串匹配,麻烦的是枚举最短串的子序列需要考虑所有循环节,而匹配的时候也要去匹配其他串的所有循环节,比赛的时候和队友一起敲了一个多小时

怕TLE所以加了一个hash,来判断当前子序列是否已经查询过,结果出来1ms,还是很优秀的

#include<bits/stdc++.h>
using namespace std;
#define LL long long
char s[15][20];
int len[15];

map<LL ,bool>vis;

int n,ans;
char anss[15];

int lensub;
char sub[15];


void deal(){
    LL tt=0;
    for(int i=1;i<=lensub;i++)tt=100*tt+sub[i];
    if(vis.find(tt)!=vis.end())return;
    vis[tt]=true;

    for(int i=2;i<=n;i++){
        int f=0;
        for(int j=1;j<=len[i];j++){ int en=j+len[i]-1;
            int ar=j-1;
            for(int k=1;k<=lensub;k++){
                ar++;
                while(s[i][ar]!=sub[k]&&ar<=en)ar++;
                if(ar>en)break;
                else if(k==lensub)f=1;
            }
            if(f==1)break;
        }
        if(f==0)return;
    }
    if(lensub>ans){

        //    debug();

        for(int i=1;i<=lensub;i++)
        anss[i]=sub[i];
        ans=lensub;return;
    }
    else if(lensub==ans){
        bool sma=0;
        for(int i=1;i<=lensub;i++){
            if(anss[i]!=sub[i]){
                if(anss[i]>sub[i]){
                    for(int j=1;j<=lensub;j++)anss[j]=sub[j];
                }
                break;
            }
        }
    }
}

void dfs(int now,int en){
    if(now==en+1){
        if(lensub>0)deal();
        return;
    }
    dfs(now+1,en);
    sub[++lensub]=s[1][now];
    dfs(now+1,en);
    lensub--;
}
int main(){
    while(~scanf("%d",&n)){
        vis.clear();
        ans=0;
        int tmps=1;
        for(int i=1;i<=n;i++){
            scanf("%s",s[i]+1);
            len[i]=strlen(s[i]+1);
            if(len[i]<len[tmps]) tmps=i;
            for(int j=1;j<=len[i]-1;j++)
                s[i][j+len[i]]=s[i][j];
            s[i][2*len[i]]='/0';
        }
        if(tmps!=1){
            swap(s[1],s[tmps]);
            swap(len[1],len[tmps]);
        }
        for(int i=1;i<=len[1];i++){
            lensub=0;
            dfs(i,i+len[1]-1);
        }
        if(ans==0)printf("0\n");
        else anss[ans+1]='\0', printf("%s\n",anss+1);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值