蓝桥杯-算法提高-Cowboys

来源:互联网 发布:小满crm软件 编辑:程序博客网 时间:2024/06/06 16:52

                                                                         算法训练 Cowboys  

                                    时间限制:2.0s   内存限制:256.0MB

问题描述
  一个间不容发的时刻:n个牛仔站立于一个环中,并且每个牛仔都用左轮手枪指着他旁边的人!每个牛仔指着他顺时针或者逆时针方向上的相邻的人。正如很多西部片那样,在这一刻,绳命是入刺的不可惜……对峙的场景每秒都在变化。每秒钟牛仔们都会分析局势,当一对相邻的牛仔发现他们正在互指的时候,就会转过身。一秒内每对这样的牛仔都会转身。所有的转身都同时在一瞬间发生。我们用字母来表示牛仔所指的方向。“A”表示顺时针方向,“B”表示逆时针方向。如此,一个仅含“A”“B”的字符串便用来表示这个由牛仔构成的环。这是由第一个指着顺时针方向的牛仔做出的记录。例如,牛仔环“ABBBABBBA”在一秒后会变成“BABBBABBA”;而牛仔环“BABBA”会变成“ABABB”。 这幅图说明了“BABBA”怎么变成“ABABB” 一秒过去了,现在用字符串s来表示牛仔们的排列。你的任务是求出一秒前有多少种可能的排列。如果某个排列中一个牛仔指向顺时针,而在另一个排列中他指向逆时针,那么这两个排列就是不同的。
输入格式
  输入数据包括一个字符串s,它只含有“A”和“B”。
输出格式
  输出你求出来的一秒前的可能排列数。
数据规模和约定
  s的长度为3到100(包含3和100)
样例输入
BABBBABBA
样例输出
2
样例输入
ABABB
样例输出
2
样例输入
ABABAB
样例输出
4
样例说明
  测试样例一中,可能的初始排列为:"ABBBABBAB"和 "ABBBABBBA"。
  测试样例二中,可能的初始排列为:"AABBB"和"BABBA"。

P.s:
“A”表示顺时针方向,“B”表示逆时针方向。当一对相邻的牛仔发现他们正在互指的时候,就会转过身。说明将‘BA’转化为‘AB’;
然而 牛仔环“ABBBABBBA”在一秒后会变成“BABBBABBA”;而牛仔环“BABBA”会变成“ABABB” 说明是将‘AB’转化为‘BA’;
以给的例子为准。(样例似乎两者都可)

思路: 动态规划   
dp[i][0] 表示第 i 个数不与前者交换得到,dp[i][1]表示第i个数与前者交换得到
如果当前数与前者相等,则采用 dp[i][0] = dp[i-1][0] + dp[i-1][1];
如果当前数为A,前者为B ,则 ‘AB’ 不可能是‘BA’变化得到,且前一个数必定经过了交换,dp[i][0] = dp[i-1][1]; dp[i][1] = 0; 
如果当前数为B,前者为A ,则 ‘BA’     可能是‘AB’变化得到,dp[i][0] = dp[i-1][0] + dp[i-1][1]; dp[i][1] = dp[i-2][0] + dp[i-2][1]; 
如果都是 A 或B 直接输出 1;
否则一定可以找到一个 BA ,先不管当前BA的可能取值,设该‘B’ 的位置为cot,取st = cot+2,ed = cot - 1,初始化dp[st][1] = 0,
dp[st][0]=1; 从st运算到ed ,st++;
取 sum = dp[st][0] + dp[st][1];
 如果 BA 之前是 AA,则一定要变为 AAAB,如果BA之后是BB,则一定要变为 ABBB,答案即为sum;
 如果 BA 之前是 B 且 BA 之后 是 A,则 BA 可变可不变;
 如果 BA 之前是 BA 或者 BA 之后 是 BA,则 st+=2 或 ed -=2,即 BABA 可能由 ABBA 或者 BAAB得到,这时候还要考虑 s 为 BABA 与 BABABA 的情况。
 
#include <queue>#include <functional>#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <stack>#include <vector>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <assert.h>#define REP(i,k,n) for(int i=k;i<n;i++)#define REPP(i,k,n) for(int i=k;i<=n;i++)#define scan(d) scanf("%d",&d)#define scann(n,m) scanf("%d%d",&n,&m)#define mst(a,k)  memset(a,k,sizeof(a));#define LL long long#define eps 1e-8#define INF 0x3f3f3f3f#define mod 1000000007#define PI acos(-1.)using namespace std;#define N 105#define M 10005int dp[N][2];string s;int main(){   cin>>s;   bool flag = 0;   int len = s.length();   for(int i=1;i<len;i++){      if(s[i]!=s[0]){         flag = 1;         break;      }   }   if(!flag){                     //如果都为 ‘A’或 ‘B’      cout<<1; return 0;   }   int cot;   for(int i=0;i<len;i++){        //找到 ‘BA’       if(s[ (i+1) %len] == s[i] - 1){         cot = i; break;      }   }   int st = (cot + 2) % len;   int ed = (cot - 1 + len) % len;   dp[st][0] = 1;   dp[st][1] = 0;   while(st != ed){      st = (st+1) % len;      if(s[st]==s[(st-1+len) %len]){         dp[st][0] = dp[ (st-1+len) %len][0] + dp[(st-1+len) %len][1];         dp[st][1] = 0;      }else if(s[st] == s[(st-1+len) %len] + 1){       dp[st][0] = dp[(st-1+len) %len][1];       dp[st][1] = 0;      }else{       dp[st][0] = dp[(st-1+len) %len][0] + dp[(st-1+len) %len][1];       dp[st][1] = dp[(st-2+len) %len][0] + dp[(st-2+len) %len][1];       if(dp[st][1] == 0) dp[st][1] = 1;      }   }   int sum = dp[st][0] + dp[st][1];    if(s[(cot + 2) % len]=='B' && s[(cot + 3) % len]=='B'){      cout<<sum; return 0;                 //如果是 BABB   }   if(s[(cot - 1 + len) % len]=='A' && s[(cot -2 + len) % len]=='A'){      cout<<sum; return 0;                 // 如果是 AABA   }   int length = 2;   st = (cot + 2) % len;   ed = (cot - 1 + len) % len;   if(s[(cot + 2) % len]=='B' && s[(cot + 3) % len]=='A'){      st = (st + 2) % len;      length +=2;   }    if(s[(cot - 1 + len) % len]=='A' && s[(cot -2 + len) % len]=='B'){      ed =(ed - 2 + len) % len;      length+=2;   }   if(length>=len){              //如果 是 BABA 或者 BABABA       cout<<sum+1; return 0;   }   memset(dp,0,sizeof(dp));      //注意清空   dp[st][0] = 1;   dp[st][1] = 0;    while(st != ed){      st = (st+1) % len;      if(s[st]==s[(st-1+len) %len]){         dp[st][0] = dp[ (st-1+len) %len][0] + dp[(st-1+len) %len][1];         dp[st][1] = 0;      }else if(s[st] == s[(st-1+len) %len] + 1){       dp[st][0] = dp[(st-1+len) %len][1];       dp[st][1] = 0;      }else{       dp[st][0] = dp[(st-1+len) %len][0] + dp[(st-1+len) %len][1];       dp[st][1] = dp[(st-2+len) %len][0] + dp[(st-2+len) %len][1];       if(dp[st][1] == 0) dp[st][1] = 1;      }   }   sum += dp[st][0] + dp[st][1];   cout<<sum;   return 0;}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 捷信分期逾期了怎么办 欠捷信7万还不了怎么办 苹果6s阴阳屏怎么办 碰到碰瓷的人怎么办 如果遇到碰瓷的怎么办 对交通事故责任认定书不服怎么办 违停15天没处理怎么办 衣服反光条掉了怎么办 脸过敏起小疙瘩怎么办 过敏怎么办怎么好得快 眉毛在眉骨下面怎么办 踩到地雷怎么办知乎 在边境踩到地雷怎么办 插在花泥里的花怎么办 瓶插绣球花蔫了怎么办 水养绣球花蔫了怎么办 鲜切绣球花蔫了怎么办 崩坏2仓库满了怎么办 dnf88级没任务了怎么办 0号柴油冻住了怎么办 不小心喝了生水怎么办 不小心吃了蟑螂怎么办 以租代购还不起怎么办 孩子被教官打了怎么办 三岁宝宝叛逆期怎么办 三岁宝宝很叛逆怎么办 孩子不听话怎么办有什么方法呢 打了三岁的宝宝怎么办 2岁半宝宝不听话怎么办 心里素质不好容易紧张怎么办 孩子二年级成绩差怎么办 遇到素质低的人怎么办 孩子上课注意力不集中怎么办 素质报告册丢了怎么办 潞城镇剩下5个村怎么办 高三复读生学籍怎么办 被检精子总数少怎么办 前向运动精子17%怎么办 精子形态正常率1怎么办 精子形态正常率2怎么办 精子头部畸形率高怎么办