codejam 2016 Round A APAC Test

点击打开链接

1.Googol String 对半去找点,用flag标记一下 对称的次数。

int main()
{
    int Tcase;
    if(freopen("A-large-practice.in","r",stdin)==NULL)printf("failed!\n");
    if(freopen("A-large-practice.out","w",stdout)==NULL)printf("failed!\n");
    long long k;
    long long len[100];
    len[0] = 0;
    int lenid = 0;
    while(len[lenid] < 1e18){
        len[lenid+1] = len[lenid] * 2 + 1;
        lenid++;
    }
    long long ans;
    bool flag;
    int tid;
    while(scanf("%d",&Tcase) == 1){
        for(int tcase = 1;tcase<= Tcase;tcase++){
            scanf("%lld",&k);
            if(k == 1) ans = 0;
            else{
                flag = true;
                tid = lenid;
                while(k > 0){
                    while(tid >= 0 && k < len[tid]){
                        tid--;
                    }
                    if(k == len[tid] || k == len[tid+1] || k == len[tid]+1){
                        if(k != len[tid]+1)flag = !flag;
                        if(flag)ans = 0;
                        else ans = 1;
                        break;
                    }
                    k = len[tid+1] + 1 - k;
                    flag = !flag;
                }
            }
            printf("Case #%d: %lld\n",tcase,ans);
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
2.gCube  乘法越界, 用log转换成加法,本题精度允许。

int main()
{
    int Tcase;
    if(freopen("B-large-practice.in","r",stdin)==NULL)printf("failed!\n");
    if(freopen("B-large-practice.out","w",stdout)==NULL)printf("failed!\n");
    int len[1000];
    int N,M,L,R;
    double mul,high,low,mid,dim,tmppow;
    while(scanf("%d",&Tcase) == 1){
        for(int tcase = 1;tcase<= Tcase;tcase++){
            scanf("%d %d",&N,&M);
            for(int i = 0;i < N;i++){
                scanf("%d",&len[i]);
            }
            printf("Case #%d:\n",tcase);
            while(M--){
                scanf("%d %d",&L,&R);
                mul = 0;
                for(int i =L;i<=R;i++)
                        mul += log(len[i]);
                high  = 1e9,low = 1;
                dim = (R-L +1);
                while(high-low > 1e-10){
                    mid = (high + low )/ 2;
                    tmppow =  dim*log(mid);
                    if(mul-tmppow > 1e-10){
                        low = mid;
                    }else if(tmppow - mul > 1e-10){
                        high = mid;
                    }else break;
                }
                mid = (high+low) / 2;
                printf("%.9lf\n",mid);
            }
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

3.gCampus floyd全源最短路,保存原来存在的路径,如果新的最短路比原来存在的路短,那么就是原来的路可以被替换,本题有点恶心的是有若干起点终点重合的路径。

int main()
{
    int Tcase;
    if(freopen("C-large-practice.in","r",stdin)==NULL)printf("failed!\n");
    if(freopen("C-large-practice.out","w",stdout)==NULL)printf("failed!\n");
    int N,M;
    int oldpath[100][100];
    int newpath[100][100];
    vector<int> Pathid[100][100];
    int U,V,C;
    vector<int> res;
    while(scanf("%d",&Tcase) == 1){
        for(int tcase = 1;tcase<= Tcase;tcase++){
            scanf("%d %d",&N,&M);
            res.clear();
            memset(oldpath,0,sizeof(oldpath));
            memset(newpath,0,sizeof(newpath));
            for(int i = 0;i < N;i++)for(int j = 0;j < N;j++)Pathid[i][j].clear();

            for(int pathid = 0;pathid < M;pathid++){
                scanf("%d %d %d",&U,&V,&C);
                if(U==V){
                        res.push_back(pathid);
                        continue;
                }else if(oldpath[U][V]!=0){
                    if(C < oldpath[U][V]){
                        for(int i = 0;i < Pathid[U][V].size();i++)
                            res.push_back(Pathid[U][V][i]);
                        Pathid[U][V].clear();
                        Pathid[V][U].clear();
                    }else if (C > oldpath[U][V]){
                        res.push_back(pathid);
                        continue;
                    }else{
                        Pathid[U][V].push_back(pathid);
                        Pathid[V][U].push_back(pathid);
                        continue;
                    }
                }
                Pathid[U][V].push_back(pathid);
                Pathid[V][U].push_back(pathid);
                oldpath[U][V] =oldpath[V][U] = newpath[U][V]= newpath[V][U]=C;
            }

            for(int k = 0;k < N;k++){
                for(int i = 0;i < N;i++){
                    for(int j = 0;j < N;j++){
                        if(i == j)continue;
                        if(newpath[i][k] != 0 && newpath[k][j]!=0&&
                           (newpath[i][j] == 0 ||newpath[i][k] + newpath[k][j] < newpath[i][j]))
                            newpath[i][j] = newpath[j][i] = newpath[i][k] + newpath[k][j] ;
                    }
                }
            }
            printf("Case #%d:\n",tcase);
            for(int i = 0;i < N;i++){
                for(int j = i+1;j < N;j++){
                        if(oldpath[i][j] != 0 && newpath[i][j] != oldpath[i][j]){
                            for(int ii = 0;ii < Pathid[i][j].size();ii++)
                                res.push_back(Pathid[i][j][ii]);
                        }
                }
            }
            sort(res.begin(),res.end());
            for(int i = 0;i < res.size();i++)
                printf("%d\n",res[i]);
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

4.gSnake 数据描述里的范围比较吓人,但是,实际时间长度 最多也就X的上限+2倍的R或者L。

程序效率感觉有点低。

int main()
{
    int Tcase;
    if(freopen("D-large-practice.in","r",stdin)==NULL)printf("failed!\n");
    if(freopen("D-large-practice.out","w",stdout)==NULL)printf("failed!\n");

    int S,R,C;

    map<Point,int> flag;
    set<Point> foodeaten;
    queue<Point> snake;
    CMD cmds[100000];

    int cur_dir;
    Point cur_point;
    Point tmp_point;
    int timenow;
    int cmdid;
    bool printflag;
    while(scanf("%d",&Tcase) == 1){
        for(int tcase = 1;tcase<= Tcase;tcase++){
            scanf("%d %d %d",&S,&R,&C);
            for(int i = 0;i < S;i++){
                scanf("%d %c",&cmds[i].first,&cmds[i].second);
            }
            flag.clear();
            foodeaten.clear();
            while(!snake.empty())
                snake.pop();
            cur_dir = 0;//0 Right, 1 Down, 2 Left, 3 Up
            cur_point = {0,0};//题目中是1,1开始,我这里自己调整到0,0
            snake.push(cur_point);
            flag[cur_point]++;
            timenow = 1;
            cmdid = 0;
            printflag=true;
            printf("Case #%d: ",tcase);
            int counter = 0;
            while(timenow <= 1e9 && counter <1000000){
                if(cur_dir == 0){
                    cur_point.second = (cur_point.second+1)% R ;
                }else if(cur_dir == 1){
                    cur_point.first = (cur_point.first+1) % C ;
                }else if(cur_dir == 2){
                    cur_point.second = (cur_point.second+R-1) % R;
                }else{
                    cur_point.first = (cur_point.first+C-1) % C ;
                }
                snake.push(cur_point);
                if(((cur_point.first)%2) + ((cur_point.second)%2) == 1 && foodeaten.find(cur_point)==foodeaten.end()){
                    foodeaten.insert(cur_point);
                }else{
                    tmp_point = snake.front();
                    flag.erase(tmp_point);
                    snake.pop();
                }
                flag[cur_point]++;
                if(flag[cur_point] > 1){
                    printf("%d\n",snake.size());
                    printflag = false;
                    break;
                }

                if(cmdid < S &&timenow == cmds[cmdid].first){
                    if(cmds[cmdid].second == 'R')
                        cur_dir = (cur_dir+1)%4;
                    else
                        cur_dir = (cur_dir+3)%4;
                    cmdid++;
                    counter=0;
                }
                timenow++,counter++;
            }
            if(printflag)printf("%d\n",snake.size());
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值