例题4-1 Ancient Cipher UVA - 1339
Ancient Roman empire had a strong government system with various departments, including a secret
service department. Important documents were sent between provinces and the capital in encrypted
form to prevent eavesdropping. The most popular ciphers in those times were so called substitution
cipher and permutation cipher.
Substitution cipher changes all occurrences of each letter to some other letter. Substitutes for all
letters must be different. For some letters substitute letter may coincide with the original letter. For
example, applying substitution cipher that changes all letters from ‘A’ to ‘Y’ to the next ones in the
alphabet, and changes ‘Z’ to ‘A’, to the message “VICTORIOUS” one gets the message “WJDUPSJPVT”.
Permutation cipher applies some permutation to the letters of the message. For example, applying the permutation ⟨2, 1, 5, 4, 3, 7, 6, 10, 9, 8⟩ to the message “VICTORIOUS” one gets the message
“IVOTCIRSUO”.
It was quickly noticed that being applied separately, both substitution cipher and permutation
cipher were rather weak. But when being combined, they were strong enough for those times. Thus,
the most important messages were first encrypted using substitution cipher, and then the result was
encrypted using permutation cipher. Encrypting the message “VICTORIOUS” with the combination of
the ciphers described above one gets the message “JWPUDJSTVP”.
Archeologists have recently found the message engraved on a stone plate. At the first glance it
seemed completely meaningless, so it was suggested that the message was encrypted with some substitution and permutation ciphers. They have conjectured the possible text of the original message that
was encrypted, and now they want to check their conjecture. They need a computer program to do it,
so you have to write one.
Input
Input file contains several test cases. Each of them consists of two lines. The first line contains the
message engraved on the plate. Before encrypting, all spaces and punctuation marks were removed, so
the encrypted message contains only capital letters of the English alphabet. The second line contains
the original message that is conjectured to be encrypted in the message on the first line. It also contains
only capital letters of the English alphabet.
The lengths of both lines of the input file are equal and do not exceed 100.
Output
For each test case, print one output line. Output ‘YES’ if the message on the first line of the input file
could be the result of encrypting the message on the second line, or ‘NO’ in the other case.
Sample Input
JWPUDJSTVP
VICTORIOUS
MAMA
ROME
HAHA
HEHE
AAA
AAA
NEERCISTHEBEST
SECRETMESSAGES
Sample Output
YES
NO
YES
YES
NO
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
char s[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char s1[105],s2[105];
int a[30],b[30];
while(cin>>s1>>s2){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<strlen(s1);i++){
a[s1[i]-'A']++;
b[s2[i]-'A']++;
}
sort(a,a+26);
sort(b,b+26);
bool flag=true;
for(int i=0;i<26;i++){
if(a[i]!=b[i]){
flag=false;
break;
}
}
if(flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
例题4-2 Hangman Judge UVA - 489
In “Hangman Judge,” you are to write a program that judges a series of Hangman games. For each
game, the answer to the puzzle is given as well as the guesses. Rules are the same as the classic game
of hangman, and are given as follows:
1. The contestant tries to solve to puzzle by guessing one letter at a time.
2. Every time a guess is correct, all the characters in the word that match the guess will be “turned
over.” For example, if your guess is ‘o’ and the word is “book”, then both ‘o’s in the solution will
be counted as “solved”.
3. Every time a wrong guess is made, a stroke will be added to the drawing of a hangman, which
needs 7 strokes to complete. Each unique wrong guess only counts against the contestant once.
| |
| O
| /|\
| |
| / \
|_
| |__
|___|
4. If the drawing of the hangman is completed before the contestant has successfully guessed all the
characters of the word, the contestant loses.
5. If the contestant has guessed all the characters of the word before the drawing is complete, the
contestant wins the game.
6. If the contestant does not guess enough letters to either win or lose, the contestant chickens out.
Your task as the “Hangman Judge” is to determine, for each game, whether the contestant wins,
loses, or fails to finish a game.
Input
Your program will be given a series of inputs regarding the status of a game. All input will be in lower
case. The first line of each section will contain a number to indicate which round of the game is being
played; the next line will be the solution to the puzzle; the last line is a sequence of the guesses made
by the contestant. A round number of ‘-1’ would indicate the end of all games (and input).
Output
The output of your program is to indicate which round of the game the contestant is currently playing
as well as the result of the game. There are three possible results:
You win.
You lose.
You chickened out.
Sample Input
1
cheese
chese
2
cheese
abcdefg
3
cheese
abcdefgij
-1
Sample Output
Round 1
You win.
Round 2
You chickened out.
Round 3
You lose.
AC代码:
#include<iostream>
#include<cstring>
using namespace std;
bool judge(bool a[]){
for(int i=0;i<26;i++){
if(a[i])return 0;
}
return true;
}
int main()
{
int round;
while(cin>>round && round!=-1){
char s1[1000];
char s2[1000];
bool a[30]={0},b[30]={0};
cin>>s1>>s2;
for(int i=0;i<strlen(s1);i++){
a[s1[i]-'a']=1;
}
int cnt=0;
for(int i=0;i<strlen(s2);i++){
if(!b[s2[i]-'a']){
b[s2[i]-'a']=1;
if(a[s2[i]-'a']){
a[s2[i]-'a']=0;
}
else{
cnt++;
}
}
if(cnt>=7){
cout<<"Round "<<round<<endl;
cout<<"You lose."<<endl;
break;
}
if(cnt<7 && judge(a)){
cout<<"Round "<<round<<endl;
cout<<"You win."<<endl;
break;
}
}
if(cnt<7 && !judge(a)){
cout<<"Round "<<round<<endl;
cout<<"You chickened out."<<endl;
}
}
return 0;
}
例题4-3 The Dole Queue UVA - 133
In a serious attempt to downsize (reduce) the dole queue, The New National Green Labour Rhinoceros
Party has decided on the following strategy. Every day all dole applicants will be placed in a large
circle, facing inwards. Someone is arbitrarily chosen as number 1, and the rest are numbered counterclockwise up to N (who will be standing on 1’s left). Starting from 1 and moving counter-clockwise,
one labour official counts off k applicants, while another official starts from N and moves clockwise,
counting m applicants. The two who are chosen are then sent off for retraining; if both officials pick
the same person she (he) is sent off to become a politician. Each official then starts counting again
at the next available person and the process continues until no-one is left. Note that the two victims
(sorry, trainees) leave the ring simultaneously, so it is possible for one official to count a person already
selected by the other official.
Input
Write a program that will successively read in (in that order) the three numbers (N, k and m; k, m > 0,
0 < N < 20) and determine the order in which the applicants are sent off for retraining. Each set of
three numbers will be on a separate line and the end of data will be signalled by three zeroes (0 0 0).
Output
For each triplet, output a single line of numbers specifying the order in which people are chosen. Each
number should be in a field of 3 characters. For pairs of numbers list the person chosen by the counterclockwise official first. Separate successive pairs (or singletons) by commas (but there should not be a
trailing comma).
Note: The symbol ⊔ in the Sample Output below represents a space.
Sample Input
10 4 3
0 0 0
Sample Output
␣␣4␣␣8,␣␣9␣␣5,␣␣3␣␣1,␣␣2␣␣6,␣10,␣␣7
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
bool check_empty(int a[]){
for(int i=0;i<25;i++)
if(a[i]) return false;
return true;
}
int main()
{
int n,k,m;
int a[30];
while(cin>>n>>k>>m){
if(n==0 && k==0 && m==0)break;
memset(a,0,sizeof(a));
for(int i=0;i<n;i++) a[i]=i+1;
int first=1;
int n1=0,n2=0;
while(!check_empty(a)){
int kk=0,mm=0;
int tmp1,tmp2;
while(1){
if(a[(n1+n)%n]){
kk++;
}
if(kk==k){
tmp1=a[(n1+n)%n];
break;
}
n1++;
}
while(1){
if(a[n-1-(n2+n)%n]){
mm++;
}
if(mm==m){
tmp2=a[n-1-(n2+n)%n];
break;
}
n2++;
}
a[(n1+n)%n]=0;
a[n-1-(n2+n)%n]=0;
if(tmp1==tmp2){
if(first){
printf("%3d",tmp1);
first=0;
}
else{
printf(",%3d",tmp1);
}
}
else{
if(first){
printf("%3d%3d",tmp1,tmp2);
first=0;
}
else{
printf(",%3d%3d",tmp1,tmp2);
}
}
}
cout<<endl;//加上这一句就过啦
}
return 0;
}