比赛A了B, G,H,I, 赛后我独自整理了F,J, 还有A题貌似可以做,可惜没时间,下次再整理吧。
讲一下J和F的思路, 还有贴J和K的代码
J :其实就是把字母映射分成元音和辅音两组就可以了, 那么我们暴力dfs把26个字母分成2组的状态,然后根据输入的串相邻位置不能是同一组的把一大堆无用状态删去,然后找到一个有用的就停,修改一下即可。
注意:每个单词有可能用空行隔开。
F:数位统计题吧,我们先预处理出dp,cnt数组
// dp[x] x位为1的所有数的个数
// cnt[x] x位为1的所有数的1的个数
那么我们可以先让x从小到大把能减的减去,得到第n个位置在长度len的二进制数上,那么
将len-1位置1,多次从后往前扫一遍,每扫一遍就要将有些位置1,一直到结束,具体看代码吧,
细节很多,我还写了暴力程序对拍。
code J:
#include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <iostream> #include <vector> using namespace std; char str[100005], s[100005]; bool g[33][33]; char yuan[] = {"AEUOI"}; char fu[] = {"BCDFGHJKLMNPQRSTVWXYZ"}; char idx[256]; void go(char *t) { int i; int len = strlen(t); for(i = 0; i < len-1; i++) { if(t[i] >= 'A' && t[i] <= 'Z' && t[i+1] >= 'A' && t[i+1] <= 'Z') { g[t[i]-'A'][t[i+1]-'A'] = true; } } } int pos, st; bool dfs(int pos, int cnt, int st) { if(pos == 26) { if(cnt != 5) return false; bool ok = true; for(int x = 0; x < 26 && ok; x++) for(int y = 0; y < 26 && ok; y++) if(g[x][y] && (((st>>x)&1)^((st>>y)&1)^1)) { ok = false; } if(ok) { ::st = st; return true; } return false; } if(cnt < 5) if(dfs(pos+1, cnt+1, st<<1|1)) return true; if(dfs(pos+1, cnt, st<<1)) return true; return false; } int main() { freopen("javanese.in", "r", stdin); freopen("javanese.out", "w", stdout); int i; memset(g, false, sizeof(g)); while(gets(str) && str[0] != 't') { go(str); int len = strlen(str); for(i = 0; i < len; i++) s[pos++] = str[i]; s[pos++] = '\n'; } if(!dfs(0, 0, 0)) return cout<<"impossible"<<endl, 0; int idy = 0, idf = 0; // puts("~~~~~~~~`"); for(i = 0; i < 26; i++) { if(st&(1<<i)) idx[i+'A'] = yuan[idy++]; else idx[i+'A'] = fu[idf++]; } // for(i = 0; i < 26; i++) // printf("%c->%c\n", i+'A', idx[i+'A']); int len = strlen(s); // printf("len = %d\n",len); for(i = 0; i < len; i++) if(s[i] >= 'A' && s[i] <= 'Z') { s[i] = idx[s[i]]; // printf("%c %c\n", s[i], idx[s[i]]); } for(i = 0; i < len; i++) printf("%c", s[i]); puts(""); return 0; } /* A->B B->C C->D D->F E->G F->H G->J H->K I->L J->M K->N L->O M->P N->Q O->R P->S Q->T R->V S->W T->X U->Y V->A W->E X->U Y->O Z->I */
#include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <iostream> #include <vector> using namespace std; typedef long long ll; ll duipai[100005]; void debug() { //暴力对拍 int i, j; string str; for(i = 1; i <= 10000; i++) { j = i; string tp; while(j > 0) { tp += j % 2 + '0'; j >>= 1; } reverse(tp.begin(), tp.end()); bool flag = false; for(j = 0; j < (int) tp.size() - 1; j++) if(tp[j] == tp[j + 1] && tp[j] == '1') { flag = true; break; } if(!flag) { str += tp; } } for(i = 1; i <= 1000; i++) duipai[i] = duipai[i - 1] + (str[i - 1] == '1'); } int num[222]; int cal(int len, int x) { int ret = 0; for(int i = 0; i < x; i++) { ret += num[len-i]; } return ret; } ll dp[100005], cnt[100005], n; // dp[x] x位为1的所有数的个数 // cnt[x] x位为1的所有数的1的个数 int main() { freopen("fibonacci.in", "r", stdin); freopen("fibonacci.out", "w", stdout); int i; cnt[0] = 0; cnt[1] = 1; dp[0] = 1; dp[1] = 1; ll s1 = 0, s2 = 1; for(i = 2; i <= 100000; i++) { cnt[i] = s1 + s2; s1 += cnt[i - 1]; dp[i] = s2; s2 += dp[i - 1]; } //debug(); while(cin >> n) { if(!n) { cout << "0" << endl; continue; } ll ans = 0; for(i = 1;; i++) { if(n >= dp[i] * i) { n -= dp[i] * i; ans += cnt[i]; } else break; } int len = i; memset(num, 0, sizeof(num)); num[len-1] = 1; if(n <= len) { ans += cal(len-1, n); cout << ans << endl; continue; } int pre = 1, pos = len - 2; while(true) { for(i = 0; i <= pos; i++) { if(n >= dp[i] * len) { n -= dp[i] * len; ans += cnt[i] + pre * dp[i]; } else break; } num[i-1] = 1; if(n <= len) { ans += cal(len-1, n); break; } else pos = i - 2; pre++; } cout << ans << endl; } return 0; }