字符加密 cipher
阿新 • • 發佈:2019-02-10
div target std gist 字符串 str -s display 行為
評測傳送門
Description:
Valentino 函數的定義:
對於一個由數字和小寫字母組成的字符串 S,兩個整數 K,M,將 S 視為一個 P 進制數,定義:
Valentino(S, K, M) = KS mod M
對於一個字串對應的進制 P,現作出如下規定:
S = “12445”,你應該將它視為一個 6 進制數:124456 = 190110 。
S = “c0ab5h”,你應該將它視為一個 18 進制數:c0ab5h18 = 2273680710 。
即,對於一個由數字和小寫字母組成的字符串 S,將’a’視為 10,’b’視為 11,...,’z’視為 35,你應該找到最小的 P,使得 S 是一個合法的 P 進制數。
現在,Valentino 手上有若幹個由數字和小寫字母組成的字符串。他選定了兩個數 K,M,想求出每個字符串的 Valentino 函數的十進制表示。但是由於字符串實在太長了,Valentino 實在算不過來,所以他只好求助於你。Input
第 1 行為兩個正整數 K, M。
接下來每行一個由數字和小寫字母組成的字符串,代表你要處理的字符串。Output
每行一個整數,第 i 行輸出第 i 個字符串的 Valentino 函數值,以十進制表示。
正解:
我覺得solution講得超級清楚啊(圖點開看還是挺清楚的)
但是要補充解釋一個地方:x的含義是 kpi,
pi是p的i次方
CODE:
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #define R register 6 #define go(i,a,b) for(R int i=a;i<=b;i++) 7 #define yes(i,a,b) for(R int i=a;i>=b;i--) 8 #define M 100000+1 9 #define ll long long 10 using namespaceView Codestd; 11 ll k,m,n,x,len,a[M],as; 12 string s; 13 ll ksm(ll x,ll y) 14 { 15 ll ans=1; 16 while(y) 17 { 18 if(y&1) ans=ans*x%m; 19 x=x*x%m;y>>=1; 20 } 21 return ans%m; 22 } 23 int main() 24 { 25 scanf("%lld%lld",&k,&m); 26 while(cin>>s) 27 { 28 len=s.length()-1;n=0;as=1;x=k; 29 go(i,0,len) 30 { 31 if(s[i]>=‘0‘&&s[i]<=‘9‘) a[i]=s[i]-‘0‘; 32 else a[i]=s[i]-‘a‘+10; 33 n=max(n,a[i]); 34 }n+=1; 35 yes(i,len,0) 36 { 37 as=as*ksm(x,a[i])%m; 38 x=ksm(x,n); 39 } 40 printf("%lld\n",as); 41 } 42 return 0; 43 }
字符加密 cipher