【HDOJ】4662 MU Puzzle
【题目】http://acm.hdu.edu.cn/showproblem.php?pid=4662
【报告】
按照题目意思,第一条,可以把M后面的复制一份,第二条,可以把3个I换成一个U,第三条,可以把2个U删掉。把I算成1,,那么一个字符串可以对应一个数字S(但一个S不一定对应一个字符串)。第一条,显然,就是S*=2;第二条,一个U就可以算成3个I,也就是3;第三条,一次删去两个U,相当于S-=6。
题目问的是有限步骤是否可以达成。我们把初始状态当成1,把结束字符串转换为一个数字。相当于是否可以通过这3种变换方式(其实只有2种),把1变成目标数字S。通过数学计算,相当于求 s=2^x1-6x2是否有正整数解(x1,x2为未知数)因为数据范围原因,可以直接暴力求解。
还有一些注意的,就是输入。首先,单独一个M应该是算No的,一个串里面出现2个M也是不行的,第一个字符不是M也是不行的。(被坑惨了。。)
这不是标程给的算法,苏牛说我这个算法能A完全是因为数据比较弱。不是很理解的说。。。
【程序】
// Task: 4662 MU Puzzle
// Designer: Rsky 2013/08/10
#include
#include
#include
#include
using namespace std;
#define L 1000000
char st[L+1];
int main()
{
int t;
scanf("%d",&t);
while
(t--)
{
scanf("%s",st);
if (strlen(st)<=1||st[0]!='M')
{
printf("No\n");
continue;
}
int s=0;
bool flag=true;
for (int i=strlen(st)-1;i>=1;i--)
if (st[i]=='I') s++;
else if (st[i]=='U') s+=3;
else flag=false;
if (!flag)
{
printf("No\n");
continue;
}
// cout << "s=" <<
s << endl;
int k1,k2;
bool ans=false;
for (k1=1;k1>0;k1*=2)
if (k1>=s&&(k1-s)%6==0)
{
//
cout << k1 << " " << (k1-s)/6 <<
endl;
ans=true;

浙公网安备 33010602011771号