1. 程式人生 > >字符加密 cipher

字符加密 cipher

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 namespace
std; 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 }
View Code

字符加密 cipher