2008-2009 ACM-ICPC Northeastern European Regional Contest (NEERC 08) (2013区域赛练习)

比赛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
 */

code F:

#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;
}


A
Aerodynamics 1
aerodynamics.in / aerodynamics.out
2 s, 256 MB
   x60
B
Blind Walk 1
standard input/output
2 s, 256 MB
   x175
C
Clock 1
clock.in / clock.out
2 s, 256 MB
   x5
D
Drive through MegaCity 1
drive.in / drive.out
2 s, 256 MB
   x4
E
Exclusive Access 1
exclusive.in / exclusive.out
2 s, 256 MB
   x2
F
Fibonacci System 1
fibonacci.in / fibonacci.out
2 s, 256 MB
   x80
G
Giant Screen 1
giant.in / giant.out
2 s, 256 MB
   x201
H
Hell on the Markets 1
hell.in / hell.out
2 s, 256 MB
   x159
I
iSharp 1
isharp.in / isharp.out
2 s, 256 MB
   x198
J
Javanese Cryptoanalysis 1
javanese.in / javanese.out
2 s, 256 MB
   x111
K
KINA Is Not Abbreviation 1
kina.in / kina.out
2 s, 256 MB
   x14

你可能感兴趣的:(2008-2009 ACM-ICPC Northeastern European Regional Contest (NEERC 08) (2013区域赛练习))