2014西安全国邀请赛

  D - Wow! Such String!:

  这道字符串题居然正解是欧拉图,我也是看醉了...欧拉图虽然学过,但可能理解得还不是很深,所以对这种题不敏感。

  这道题解法是把每四个字符组成的字符串看成是一个点,每个点有26个入边和26个出边,可以证明这是一个欧拉图。然后遍历找一下欧拉图就行了。

  不过...一开始我是自己建了个图...结果超内存...然后想打表...结果根本不让我交...实在无奈,改成了每个点自己找下一个点,不连边。(现在想想连边好像是没有必要的)另,看题的时候还是要仔细看题目要求,尽量不犯错。

  这题还有一个神奇的地方,就是正着遍历最多只能到104的长度,而反着遍历就能遍历完。不明原理中...(据说是优先级的原因)

  原来又是我想错了,每个节点遍历一次,其实就相当于欧拉图中的每个边遍历一次,所以应该以四个字符组成的字符串看成边,三个字符组成的字符串看成点,然后建立欧拉图。其实也并不完全错,我相当于是在枚举边。结果还是一样的。

 1 //突然感觉这题好水...
 2 //11537570  2014-08-24 21:36:32 Accepted    4850    46MS    3020K   1613 B  G++ TofE
 3 #include <iostream>
 4 #include <cstdio>
 5 #include <cstring>
 6 #define debug(x) cout<<#x<<" = "<<x<<endl
 7 using namespace std;
 8 const int maxn=456976+1;
 9 
10 int n;
11 int ans;
12 int dl[maxn*26];
13 bool vis[maxn*26];
14 char str[maxn*+3+1];
15 void bfs()
16 {
17     int v,i,tp;
18     int l=0,r=0;
19     dl[++r]=0; vis[0]=1;
20     while (l<r)
21     {
22         v=dl[++l];
23         str[l-1]=v/17576+'a';
24         tp=v%17576; tp*=26;
25         for (i=25;i>=0;i--)
26             if (!vis[tp+i])
27             {
28                 vis[tp+i]=1;
29                 dl[++r]=tp+i;
30                 break;
31             }
32     }
33     v=dl[l]; v%=17576;
34     str[r++]=v/676+'a'; v%=676;
35     str[r++]=v/26+'a'; v%=26;
36     str[r++]=v+'a'; str[r]='\0';
37     ans=r;
38 }
39 int main()
40 {
41     bfs();
42     for (;scanf("%d",&n)!=EOF;)
43     {
44         if (ans<n) puts("Impossible");
45         else printf("%s\n",str+(ans-n));
46     }
47     return 0;
48 }
View Code

——神奇的欧拉图系列

posted @ 2014-08-24 21:45  ooyyloo  阅读(428)  评论(0编辑  收藏  举报