poj 2818 密码

//poj 2818 密码

//http://poj.grids.cn/problem/2818
//开始会超时,然后思路很乱,看了别人的代码,改了一下~~
//这道题因为k的值很大的话会运行很多次,导致超时
//所以,在输入时先算出最小次变化到相同,存为数组
//再在输入k的时候模一下^_^
//每次还要注意字符串和后面要接着空格
#include<iostream>
using namespace std;
int main()
{
 int cases,k;
 int i,j;
 int num[210],index_copy[210],index[210];
 int mod_copy[210],mod[210];
 char code[210],decode[210];
 while(scanf("%d",&cases)!=EOF&&cases)
 {
  memset(num,0,sizeof num);
  for(i=1;i<=cases;i++)
   scanf("%d",&num[i]);


//预处理
  memset(index_copy,0,sizeof index_copy);
  for (i=1;i<=cases;i++)
  {
   index_copy[i] = i;
  }
  memset(mod_copy,0,sizeof mod_copy);
  for (i=1;i<=cases;i++)
  {
   int temp = index_copy[i];
   while (++mod_copy[i])
   {
    index_copy[i] = num[index_copy[i]];       
    if (temp == index_copy[i])
     break;
   }
  }


  while(scanf("%d",&k)!=EOF&&k)
  {
   memset(code,' ',sizeof code);//先置为空格
   memset(decode,' ',sizeof decode);
   for(i=1;i<=cases;i++)        //拷贝预处理
   {
    index[i]=index_copy[i];
    mod[i]=mod_copy[i];
   }
   gets(code);
   code[strlen(code)] = ' ';
   for (j=1;j<=cases;j++)//求最终的对应密码
   {
    int temp = k%mod[j];//每一次被取模后还剩多少次,这步是关键省略了之前的多次不必要计算
    for (i=1;i<=temp;i++)
    {
     index[j] = num[index[j]];
    }
   }
   for (int i=1;i<=cases;i++)//解码
   {
    decode[index[i]] = code[i];
   }
   decode[cases+1] = '/0';//补结束符
   cout<<(char*)(decode+1)<<endl;
  }
  cout<<endl;
 }
 return 0;
}

你可能感兴趣的:(poj 2818 密码)