Ural 1181 Cutting a Painted Polygon

这道题我一开始思路错了,在结束递归的时候用的是顶点数减到2,虽然也是每次去掉一个角,但是处理不了特殊情况。

看了书上的解法,这个递归结束条件就巧妙很多了,原来递归可以这样,找到一种特殊情况,当递归到这种时,就处理了退出,并不一定规模减少到最少再处理。再想想,根本的思想貌似是一致的。

题干强调了各种颜色都会有,并且相同颜色不相邻,应该不用处理吧。不过提交的时候22#出错,不知为何,先不想了。还不识别index函数,编译错了很多次。

#include <cstdio>
#include <string.h>
using namespace std;

char c[1005];
int b[1005], n, cu, num[3], s[505], e[505];
bool flag;

void count_color(){
    for(int i=0;i<n;i++){
        switch(c[i]){
            case 'R':
                num[0]++;
                break;
            case 'G':
                num[1]++;
                break;
            case 'B':
                num[2]++;
                break;
            default:
                break;
        }
    }
}

int sp_case(){
    int in = -1;
    if(num[0] == 1){
        in = (int)(index(c, 'R') - c);
    }else if(num[1] == 1){
        in = (int)(index(c, 'G') - c);
    }else if(num[2] == 1){
        in = (int)(index(c, 'B') - c);
    }
    return in;
}

void update_num(char cc){
    switch(cc){
        case 'R':
            num[0]--;
            break;
        case 'G':
            num[1]--;
            break;
        case 'B':
            num[2]--;
            break;
        default:
            break;
    }
}

void update_str(int po, int t){
    c[po] = '\0';
    strcat(c, c+po+1);
    for(int i=po;i<t;i++)
        b[i] = b[i+1];
}

bool isok(int aa, int bb, int cc){
    return (c[aa] != c[bb] && c[aa] != c[cc] && c[bb] != c[cc]); 
}

void cut(int t){
    int spc = sp_case();
    if(spc >= 0){
        for(int i=0;i<t;i++){
            if(b[i] != b[spc] && b[i] != (b[spc]+1)%n && b[i] != (b[spc]-1+n)%n){
                s[cu] = b[spc];
                e[cu] = b[i];
                cu++;
            }
        }
        flag = 1;
        return;
    }
    int aa, bb, cc;
    for(int i=0;i<t;i++){
        if(isok(i, (i+1)%t, (i+2)%t)){
            aa = i; bb = (aa+1)%t; cc = (aa+2)%t;
            break;
        }
    }
    s[cu] = b[aa];
    e[cu] = b[cc];
    cu++;
    update_num(c[bb]);
    update_str(bb, t);
    cut(t-1);
}

int main(){
    while(~scanf("%d", &n)){
        scanf("%s", c);
        for(int i=0;i<n;i++)
            b[i] = i;
        cu = 0;
        flag = 0;
        memset(num, 0, sizeof(num));
        count_color();
        cut(n);
        if(flag){
            printf("%d\n", cu);
            for(int i=0;i<cu;i++)
                printf("%d %d\n", s[i]+1, e[i]+1);
        }else{
            printf("0\n");
        }
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值