Description
工業計算機處理器公司爲顧客量身定做了非常快速、用於專門目的的處理單元。a-C-m系列的處理器(比如1-C-2和5-C-3)的指令集只有兩種操作:
• A 數值加a • M 數值乘m
處理器接收一個整數,執行一個A和M的指令序列(即程序)來修改輸入,然後輸出結果。舉個例子,1-C-2處理器執行程序AAAM處理輸入2返回輸出10(計算過程是2→3→4→5→10),然而5-C-3處理器用相同的程序和輸入返回51(2→7→12→17→51)。
你是一個被指定做一個頂級祕密項目的a-C-m程序員。這意味着你不會被告知你的程序執行的精確輸入。但會得到四個特別的值p,q,r,s,以及下列條件
1、輸入保證是一個在p、q之間的數 2、輸出必須是一個在r,s之間的數。
給你一個a-C-m處理器和p,q,r,s這四個數。你的工作是構想最短的a-C-m程序,使得任意任意x保證p≤x≤q,返回一個輸出y使得r≤y≤s。如果有多個最短的程序,選擇字典序最小的,而一個程序即是由A和M組成的字符串。
Input
輸入包含多組數據。每組數據在一行中給你6個整數a,m,p,q,r,s,每個就像上面描述的一樣。 末行輸入6個0作爲結束。
Output
對於每組數據,在你的程序前輸出數據的編號,程序即像上面描述的一樣。輸出單詞“empty”,如果最好的程序沒有操作。輸出單詞“impossible”如果沒有程序滿足具體要求。
輸出一個用空格分隔的字符串序列,任兩個相鄰的字符串形式分別爲“nA”和“nM”,n>0。前者表示n個連續的操作A,後者表示n個連續的操作M。
Sample Input
1 2 2 3 10 20
1 3 2 3 22 33
3 2 2 3 4 5
5 3 2 3 2 3
0 0 0 0 0 0
Sample Output
Case 1: 1A 2M
Case 2: 1M 2A 1M
Case 3: impossible
Case 4: empty
HINT
所有的的a,m,p,q,r,s∈[1,1000000000],且p≤q,r≤s。
題解
感覺我已經變得奇奇妙妙了…
菜的真實
首先你可以知道,對於任意輸入一個數,最終一定可以變爲這樣的形式
主要是我沒有把這個形式後面寫成係數允許爲0的形式然後就掛了
你可以發現,在不等於的情況下這個最多隻有,然而的情況下只會用加的情況,這個判掉就可以了…
所以枚舉一下這個,我們只需要讓時滿足上式大於等於,時上式小於等於即可
我們可以得到他們的差分別是和,不妨設後面的式子爲,
我們發現均是由組成的,所以可以把,,然後構造後面的多項式
發現其實這是一個進制的數,我們把寫成進制,類似數位dp一下就可以了…
大概就是如果前面不頂兩個界,直接填0就可以了
如果頂着下界,看看這個位能不能填一個大於下界的數,讓後面的位置全部填0
否則的話按下界填就可以了
OZY天下第一!!!!!!!!!!!
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int stack[20];
inline void write(LL x)
{
if(x<0){putchar('-');x=-x;}
if(!x){putchar('0');return;}
int top=0;
while(x)stack[++top]=x%10,x/=10;
while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(LL x){write(x);putchar('\n');}
int a,m,p,q,r,s;
int sum;
int temp[2][35],ln[2],ans[35],lin[35];
void get(int x,int len,int opt)
{
memset(temp[opt],0,sizeof(temp[opt]));
LL base=1;ln[opt]=0;
for(int i=1;i<=len;i++)
{
temp[opt][++ln[opt]]=x%m;
if(i==len)temp[opt][i]=x;
x/=m;
if(!x)return ;
}
}
int num1[110],num2[110],ln1;
int as1[110],as2[110],ln2;
void work(int mx)
{
ln1=0;memset(num1,0,sizeof(num1));
for(int i=1;i<=mx;i++)
{
if(lin[i])
{
num1[++ln1]=lin[i];num2[ln1]=1;
// if(i!=mx)
ln1++;
}
if(!ln1)ln1=1;
if(i!=mx)num1[ln1]++,num2[ln1]=2;
}
if(lin[mx])ln1--;
}
int main()
{
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
int tt=0;
while(++tt)
{
memset(num2,0,sizeof(num2));
memset(as1,0,sizeof(as1));memset(as2,0,sizeof(as2));
a=read();m=read();p=read();q=read();r=read();s=read();
if(!a&&!m&&!p&&!q&&!r&&!s)break;
printf("Case %d: ",tt);
if(p>=r&&q<=s)puts("empty");
else if(q>s)puts("impossible");
else
{
if(m==1)
{
int down=(r-p)/a;if((r-p)%a)down++;
int up=(s-q)/a;if((s-q)%a)up++;
if(p+1LL*down*a>s||q+1LL*up*a>s||down>up)puts("impossible");
else printf("%dA\n",down);
}
else
{
bool tf=false;sum=(1<<31-1);
LL base=1;int del=a;a=1;
for(int i=0;i<=30;i++)
{
memset(lin,0,sizeof(lin));
if(i)base=base*m;
if(base>s||1LL*p*base>s||1LL*q*base>s)break;
int s1=r-p*base,s2=s-q*base;
if(s1<0)s1=0;
s1=(s1+del-1)/del;s2=s2/del;
get(s1,i+1,0);get(s2,i+1,1);
int tot=i,gg=0;bool yes=0,ok=1;
for(int j=max(ln[0],ln[1]);j>=1;j--)
{
if(!gg)//前面填的都是頂下界的
{
if(a*((temp[0][j]+a-1)/a)>temp[1][j]){ok=0;break;}
int num=a*((temp[0][j]+a-1)/a);
if(num>temp[0][j])tot+=num/a,lin[j]=num/a,gg=1;
else
{
if(num+a<=temp[1][j]||yes)
{
bool bk=false;
for(int k=j-1;k>=1;k--)if(temp[0][k]){bk=true;break;}
if(bk)tot+=num/a+1,lin[j]=num/a+1,gg=1;
else tot+=num/a,lin[j]=num/a;
}
else tot+=num/a,lin[j]=num/a;
}
}
else lin[j]=0;
if(temp[0][j]<temp[1][j])yes=1;
}
if(!ok)continue;
tf=1;work(i+1);
if(tot<sum)
{
sum=tot;
memcpy(as1,num1,sizeof(as1));memcpy(as2,num2,sizeof(as2));
ln2=ln1;
}
else if(tot==sum)
{
bool ok=true;
for(int i=ln1,j=ln2;i>=1,j>=1;i--,j--)
{
if(num2[i]>as2[j]){ok=false;break;}
if(num2[i]<as2[j])break;
if(num1[i]==as1[j])continue;
else
{
if(num1[i]>as1[j])
{
if(num2[i]>as2[j-1]){ok=false;break;}
else break;
}
else
{
if(as2[j]>num2[i-1]){ok=false;break;}
else break;
}
}
}
if(ok)
{
memcpy(as1,num1,sizeof(as1));memcpy(as2,num2,sizeof(as2));
ln2=ln1;
}
}
}
if(!tf)puts("impossible");
else
{
for(int i=ln2;i>=1;i--)
{
printf("%d",as1[i]);
if(as2[i]==1)putchar('A');
else putchar('M');
if(i!=1)putchar(' ');
}
puts("");
}
}
}
}
return 0;
}