Problem:
アフィン暗号
簡単な暗号法の一つに、アフィン暗号というものがあります。まず、アルファベット a〜z を a = 0, b = 1, c = 2,..., x = 23, y = 24, z = 25 と 0〜25 の数字に置き換えます。そして、以下の式で、原文のアルファベットを置換します。
$F(\gamma) = (\alpha \cdot \gamma + \beta)$ mod $26$
ただし、mod 26 は 26 で割った余りを表します。例えば、$\alpha = 3, \beta = 2$ のとき、アルファベットの 'a' (=0) は、$F(0) = (3 \cdot 0 + 2)$ mod $26 =  2$ で 'c' に、アルファベットの 'n' (=13) は $F(13) = (3 \cdot 13 + 2)$ mod $26 = 15$ で 'p' に置換されます。
このとき、$\gamma$ に対する $F(\gamma)$ が必ず 1 対 1 で対応付けられるように、$\alpha$ と $\beta$ は慎重に選ばれているものとします（$\alpha$ と 26 が互いに素であることが条件）。$\alpha = 4, \beta = 7$ のときのように、$F('a') = 7, F('n') = 7$ と、'a' も 'n' も同じ 'h' に置換されるようなことはありません。また、アルファベット以外の文字は置換されません。
暗号化された文字列を元の文章に復号したものを出力するプログラムを作成してください。元の文章には、キーワードとして
that
this
のいずれかが必ず含まれているものとします。
Input
複数のデータセットが与えられます。１行目にデータセット数 $n$ ($n \leq 30$) が与えられます。続いて $n$ 行のデータが与えられます。各データセットに英小文字と空白からなる 256 文字以内の暗号化された文章が１行に与えられます。
Output
各データセットに対して、復号した元の文章を１行に出力して下さい。
Sample Input
1
y eazqyp pnop pngtg ye obmpngt xmybp mr lygw
Output for the Sample Input
i submit that there is another point of view

Submitted solutions:

code_snippet: #include<iostream>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<list>
#include<iomanip>
#include<vector>
#include<functional>
#include<algorithm>
#include<cstdio>
#include<unordered_map>
using namespace std;
//---------------------------------------------------
//????????????????????????????????????
#define int long long
#define str string
const int inf = 999999999999999999;
struct P {
	int pos, cost;
};
bool operator<(P a, P b) { return a.cost < b.cost; }
bool operator>(P a, P b) { return a.cost > b.cost; }
struct B {
	int to, cost;
};
int gcm(int i, int j) {//?????§??¬?´???°
	if (i > j) swap(i, j);
	if (i == 0) return j;
	return gcm(j%i, i);
}
bool sfind(string s, string l) {//?????????1??????????????????2????????????
	for (int i = 0; i <= s.size() - l.size(); i++) {
		str t = "";
		for (int j = 0; j < l.size(); j++)
			t += s[i + j];
		if (t == l)
			return 1;
	}
	return 0;
}
typedef long long ll;
typedef long double ld;
//---------------------------------------------------
//+++++++++++++++++++++++++++++++++++++++++++++++++++
//---------------------------------------------------
signed main() {
	int n;
	cin >> n;
	getchar();
	for (int r = 0; r < n; r++) {
		string s;
		getline(cin, s);
		for (int i = 0; i < 26; i++) {
			for (int j = 0; j < 26; j++) {
				string a = "";
				for (int z = 0; z < s.size(); z++) {
					if (s[z] == ' ')
						a += " ";
					else
						a += (char)((((s[z] - 'a')*i + j) % 26) + 'a');
				}
				if (sfind(a, "that") || sfind(a, "this")) {
					cout << a << endl;
					goto stop;
				}
			}
		}
	stop:;
	}
	getchar(); getchar();
}
accuracy: 1
time_ms: 50
memory_kb: 3156
final_rank: 8

code_snippet: #include<iostream>
#include<string.h>
#include<vector>
#include<list>
#include<stdio.h>
#include<math.h>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#define range(i,a,b) for(int i = (a); i < (b); i++)
#define rep(i,b) range(i,0,b)
#define debug(x) cout << "debug " << x << endl;
using namespace std;

int main(){
    int n;
    char ans[257], str[257];
    while(cin >> n){
        cin.ignore();
        rep(i,n){
            cin.getline(str, sizeof(str));
            bool c = false;
            rep(i,26){
                rep(j,26){
                    rep(k,strlen(str)){
                        if(str[k] != ' ')
                            ans[k] = (i * str[k] - 'a' + j) % 26 + 'a';
                        else ans[k] = str[k];
                    }
                    if(strstr(ans, "this") != NULL || strstr(ans, "that") != NULL){
                        c = true;
                    }
                    if(c) break;
                }
                if(c) break;
            }
            ans[strlen(str)] = '\0';
            cout << ans << endl;
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 1160
final_rank: 1

code_snippet: #include <iostream>
#include <algorithm>
#include <string>
using namespace std;


bool IsCoprime(int a, int b)
{
	while (a > 0 && b > 0)
	{
		if (a < b) swap(a, b);
		a %= b;
	}
	if (a == 1 || b == 1) return true;
	return false;
}


char get(int a, int b, char c)
{
	for (int i = 0; i < 26; i++)
	{
		if ((a * i + b) % 26 == c - 'a') return char(i + 'a');
	}
}


int main()
{
	int n;
	string cip;
	string dec;

	cin >> n;
	cin.get();

	while (n--)
	{
		getline(cin, cip);
		dec = cip;

		for (int a = 0; a < 26; a++)
		{
			if (!IsCoprime(a, 26)) continue;
			for (int b = 0; b < 26; b++)
			{
				for (int i = 0; i < cip.size(); i++)
				{
					if (cip[i] == ' ') continue;
					dec[i] = get(a, b, cip[i]);
				}
				if (dec.find("that") != -1 || dec.find("this") != -1)
				{
					cout << dec << endl;
				}
			}
		}
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1212
final_rank: 3

code_snippet: #define _USE_MATH_DEFINES
#include <iostream>
#include <sstream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>

typedef long long ll;
using namespace std;

int F(int a, int b, int c){
	return (a*c+b) % 26;
}

int main(){
	int n;
	string str1;
	getline(cin,str1);

	n = atoi(str1.c_str());
	for(int i=0;i<n;i++){
		string str2;
		getline(cin,str2);

		for(int a=0;a<100;a++){
			for(int b=0;b<100;b++){
				string tmp = str2;
				for(int i=0;i<str2.size();i++){
					if(tmp[i]=='.') continue;
					if(tmp[i]==' ') continue;
					if(isdigit(tmp[i])) continue;
					tmp[i] = F(a,b,str2[i]-'a') + 'a';
				}

				if(tmp.find("that") != string::npos
					|| tmp.find("this") != string::npos){
						cout << tmp << endl;
						goto found;
				}
			}
		}
found:;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1200
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using namespace std; 
 
map<char, int> c2i;
map<int, char> i2c;
string str;
 
void init()
{
    for (char ch = 'a'; ch <= 'z'; ch++) {
	c2i[ch] = ch - 'a';
	i2c[ch - 'a'] = ch;
    }
}
 
bool serch(string s)
{
    string str;
    stringstream ss(s);
    while (ss >> str) {
        if (str == "this" || str == "that") {
            return 1;
        }
    }
    return 0;
}
 
char F(char ch, int a, int b)
{
    int num = (a * c2i[ch] + b) % 26; 
    return i2c[num];
}
 
int main()
{
    int n;
    init(); 
    cin >> n;
    cin.ignore();
    while (n--) {
	getline(cin, str);
 
	for (int i = 0; i < 26; i++) {
	    for (int j = 0; j < 26; j++) {
		string next;
		for (int k = 0; k < (int)str.size(); k++) {
		    if (islower(str[k])) {
                        next += F(str[k], i, j);
		    } else {
                        next += str[k];
                    }
                }
		if (serch(next)) {
		    cout << next << endl;
                    goto END;
		}
	    }
	}
        END:;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3004
final_rank: 6

code_snippet: #include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
string change(int a,int b,string str){
    for(int i=0;i<str.size();i++)str[i]=((str[i]-'a')*a+b)%26+'a';
    return str;
}
string out(int a,int b,string str){
    for(int i=0;i<str.size();i++){
        if('a'<=str[i]&&str[i]<='z'){
            for(int j=0;j<26;j++){
                if((j*a+b)%26+'a'==str[i]){
                    str[i]=j+'a';
                    break;
                }
            }
        }
    }
    return str;
}
int main(){
    int N;
    cin>>N;
    for(int i=0;i<N;i++){
        string str;
        if(!i)getchar();
        getline(cin,str);
        for(int j=1;;j++){
            for(int k=0;k<26;k++){
                for(int l=0;l<str.size()-3;l++){
                    if(change(j,k,"that")==str.substr(l,4)){
                        cout<<out(j,k,str)<<endl;
                        goto exit;
                    }
                    if(change(j,k,"this")==str.substr(l,4)){
                        cout<<out(j,k,str)<<endl;
                        goto exit;
                    }
                }
            }
        }
        exit:;
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1220
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define rep(i,n) for(i=0;i<n;++i)
#define each(itr,c) for(__typeof(c.begin()) itr=c.begin(); itr!=c.end(); itr++)
#define mp make_pair
#define pb push_back
#define fi first
#define sc second

int gcd(int p, int q){
  if(p<q) swap(p,q);
  while(q!=0){
    int tmp=p%q;
    p=q;
    q=tmp;
  }
  return p;
}

int main(int argc, char const *argv[]) {
  int i,j,k;

  string a="abcdefghijklmnopqrstuvwxyz";

  int n;
  scanf("%d\n",&n);
  for(int times=0; times<n; ++times){
    string s;
    getline(cin,s);
    //cout << s << endl;

    string ans;
    bool end=false;

    for(i=1; i<=25; ++i){//??¢???????????????
      if(gcd(26,i)!=1) continue;

      rep(j,26){
        //????????£?????§????¨?
        set<int> ch;
        rep(k,a.size()) ch.insert((i*k+j)%26);
        //??????
        if(ch.size()!=a.size()) continue;

        //printf("(%d,%d)\n",i,j);

        //?????????
        ans="";
        int p=0;
        rep(k,s.size()){
          if('a'<=s[k] && s[k]<='z'){
            ans+='a'+(i*(s[k]-'a')+j)%26;
          }
          else{
            ans+=s[k];
            string tmp=ans.substr(p,k-p);
            //cout << tmp << endl;

            if(tmp=="this"||tmp =="that")
              end=true;

            p=k+1;
          }
        }

        string tmp=ans.substr(p,k-p);
        //cout << tmp << endl;

        if(tmp=="this"||tmp =="that")
          end=true;


        if(end) break;
      }
      if(end) break;
    }

    std::cout << ans << std::endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1240
final_rank: 5

code_snippet: #include<iostream>
#include<string>
using namespace std;

char T[27] = "abcdefghijklmnopqrstuvwxyz";

string S, V;
int n;
int x[26];

int main() {
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		S = "";
		while (S == "") {
			getline(cin, S);
		}
		for (int j = 0; j < 26; j++)
		{
			for (int k = 0; k < 26; k++)
			{
				for (int l = 0; l < 26; l++)
				{
					x[l] = -1;
				}
				for (int l = 0; l < 26; l++)
				{
					if (x[(j*l + k) % 26] == -1)
					{
						x[(j*l + k) % 26] = l;
					}
					else
					{
						goto E;
					}
				}
				V = "";
				for (int l = 0; l < S.size(); l++)
				{
					for (int m = 0; m < 26; m++)
					{
						if (T[m] == S[l])
						{
							V += T[x[m]];
							goto G;
						}
					}
					V += S[l];
				G:;
				}
				for (int i = 0; i < S.size() - 3; i++)
				{
					if (V.substr(i, 4) == "this" || V.substr(i, 4) == "that")
					{
						cout << V << endl;
						goto H;
					}
				}
			E:;
			}
		}
	H:;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1220
final_rank: 4