标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 20821 | Accepted: 5708 |
Description
Input
Output
Sample Input
10 4 5 3 7 2 8 1 6 10 9 1 Hello Bob 1995 CERC 0 0
Sample Output
BolHeol b C RCE
题解:
给你一个位置,再给你字符串,问转换k次后的字串,暴力了下,超时了。。。然后就是用置换群,找出循环节,主要是ans[b[(j+k)%num]]=s[b[j]];
每一个位置变换(k%num)次
大神的解释拿来:
对于置换的数组(我们用next数组代替),里面的每一个元素都会存在于(有且只有)一个置换子群里面。
例如 题中数据: (4 -> 7 -> 1 -> 4)(5 -> 2 -> 3 -> 3) (8 -> 6 -> 8)(10 -> 9 -> 10)。 可找到4个子群。
思路:每个子群都有一定数目的各不相同的元素,用变量t记录子群元素个数,用son[]存储子群元素,就有son[0],son[1]...son[t-1]个元素。
那么我们可以得到如下变换规则-> 新字符数组gain[son[(k + j) % t]] = 原字符数组str[son[j]] (0 <= j <= t-1)。
公式推导过程:一个子群 有t个元素说明它的循环节为t, 经过k次置换 那么肯定就有son[(k + j) % t] = son[j];
例如 题目数据:4-1 5-1 3-1 7-1 2-1 8-1 1-1 6-1 10-1 9-1 (为了对应字符串的下标自减1) Hello+Bob+ 空格用+表示
拿子群(3 -> 6 -> 0 -> 3【已经减一】)来说,其中t = 3,son[0] = 3, son[1] = 6, son[2] = 0。
当k = 1时, { j = 0,son[(k + j) % t] = 6,gain[6] = str[3] = l
j = 1,son[(k + j) % t] = 0,gain[0] = str[6] = B
j = 2,son[(k + j) % t] = 3,gain[3] = str[0] = H
}
暴力超时:
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int INF=0x3f3f3f3f; #define mem(x,y) memset(x,y,sizeof(x)) #define SI(x) scanf("%d",&x) #define PI(x) printf("%d",x) typedef long long LL; const int MAXN=210; int pos[MAXN]; int main(){ int N; while(~scanf("%d",&N),N){ int k; char s[MAXN],ans[MAXN]; for(int i=0;i<N;i++)SI(pos[i]); while(scanf("%d%*c",&k),k){ mem(s,0); gets(s); while(k--){ for(int i=0;i<N;i++){ if(i>=strlen(s))ans[pos[i]-1]=‘ ‘; else ans[pos[i]-1]=s[i]; } ans[N]=‘\0‘; strcpy(s,ans); } puts(ans); } } return 0; }
置换群:
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int INF=0x3f3f3f3f; #define mem(x,y) memset(x,y,sizeof(x)) #define SI(x) scanf("%d",&x) #define PI(x) printf("%d",x) typedef long long LL; const int MAXN=210; int next[MAXN]; int vis[MAXN]; char ans[MAXN]; int b[MAXN]; int main(){ int N; while(~scanf("%d",&N),N){ int k; char s[MAXN]; for(int i=0;i<N;i++)SI(next[i]),next[i]--; while(scanf("%d%*c",&k),k){ gets(s); mem(vis,0); for(int i=strlen(s);i<N;i++)s[i]=‘ ‘; for(int i=0;i<N;i++){ if(!vis[i]){ int j=i,num=0; while(!vis[j]){ vis[j]=1; b[num++]=j; j=next[j]; } for(j=0;j<num;j++){ ans[b[(j+k)%num]]=s[b[j]]; } } } ans[N]=‘\0‘; puts(ans); } puts(""); } return 0; }
标签:
原文地址:http://www.cnblogs.com/handsomecui/p/5234590.html