2018 ACM-ICPC Asia Beijing Regional Contest题解

以下所有AC题解程序来自“仙客传奇”团队。


A. Jin Yong’s Wukong Ranking List

AC的C++语言程序:

#include <iostream>
#include <cstring>
#include <vector>
#include <map>
#include <string>
#include <stack>

using namespace std;

vector<int> adj[22];
map<string, int> m;
vector<string> name;
int indeg[22], crtdeg[22];

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    string a, b;
    while (cin >> n) {
        m.clear();
        memset(indeg, 0, sizeof indeg);
        for (int i = 0; i < 22; i++) adj[i].clear();
        name.clear();
        int i;
        for (i = 0; i < n; i++) {
            cin >> a >> b;
            if (!m.count(a)) m[a] = name.size(), name.push_back(a);
            if (!m.count(b)) m[b] = name.size(), name.push_back(b);
            adj[m[a]].push_back(m[b]);
            indeg[m[b]]++;
            // sort
            memset(crtdeg, 0, sizeof crtdeg);
            stack<int> s;
            int cnt = 0, crt;
            for (int i = 0; i < name.size(); i++) {
                if (!indeg[i]) s.push(i);
            }
            while (!s.empty()) {
                crt = s.top();
                s.pop();
                cnt++;
                for (int i = 0; i < adj[crt].size(); i++) {
                    crtdeg[adj[crt][i]]++;
                    if (crtdeg[adj[crt][i]] == indeg[adj[crt][i]]) s.push(adj[crt][i]);
                }
            }
            if (cnt != name.size()) {
                break;
            }
        }
        if (i != n) {
            cout << a << ' ' << b << '\n';
            for (i++; i < n; i++) cin >> a >> b;
        } else {
            cout << 0 << '\n';
        }
    }
    return 0;
}

AC的C++语言程序:

#include <bits/stdc++.h>

#define INF 0x3f3f3f3f
#define PB emplace_back
#define MP make_pair
#define fi first
#define se second
#define rep(i,a,b) for(repType i=(a); i<=(b); ++i)
#define per(i,a,b) for(repType i=(a); i>=(b); --i)
#define ZERO(x) memset(x, 0, sizeof(x))
#define MS(x,y) memset(x, y, sizeof(x))
#define ALL(x) (x).begin(), (x).end()

#define QUICKIO                  \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0);
#define DEBUG(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)

using namespace std;
using pi=pair<int,int>;
using repType=int;
using ll=long long;
using ld=long double;
using ull=unsigned long long;

const int MAXN=25;
vector<int> G[MAXN];
vector<pi> edges;
void add_edge(int u,int v)
{
    edges.PB(u,v);
    G[u].PB(edges.size()-1);
}
int vis[MAXN];
int n;
unordered_map<string,int> ma;
vector<string> idx;
int gh(string str)
{
    if(ma.find(str)==ma.end())
    {
        idx.PB(str);
        return ma[str]=idx.size()-1;
    }
    return ma[str];
}

bool has_loop()
{
    int cnt=0;
    queue<int> q;
    int deg[MAXN];
    ZERO(deg);
    rep(i,0,int(edges.size())-1)
    {
        deg[edges[i].se]++;
    }
    rep(i,0,idx.size()-1)
        if(deg[i]==0)
        {
            q.push(i);
        }
    while(!q.empty())
    {
        //cout<<"Now: "<<q.front()<<endl;
        cnt++;
        auto now=q.front(); q.pop();
        rep(i,0,int(G[now].size())-1)
        {
            deg[edges[G[now][i]].se]--;
            if(deg[edges[G[now][i]].se]==0)
                q.push(edges[G[now][i]].se);
        }
    }
    //cout<<cnt<<" and "<<idx.size()<<endl;
    return cnt!=idx.size();
}
int
main()
{
    while(cin>>n)
    {
        bool ok=true;
        idx.clear();
        ma.clear();
        rep(i,0,20) G[i].clear();
        edges.clear();
        rep(i,1,n)
        {
            string stra,strb;
            cin>>stra>>strb;
            if(!ok) continue;
            int u=gh(stra), v=gh(strb);
            //cout<<"Add: "<<u<<" "<<v<<endl;
            add_edge(u,v);
            if(has_loop())
            {
                cout<<stra<<" "<<strb<<endl;
                ok=false;
            }
        }
        if(ok) cout<<0<<endl;
    }

    return 0;
}

B. Heshen’s Account Book

AC的C++语言程序:

#include <iostream>
#include <vector>
#define gc getchar

using namespace std;
typedef unsigned long long ULL;
enum {START, ERR, LEAD, DIG};
int cnt[210];
vector<int> ans;
int line = 0, realline = 0;
void out() {
    for (int i = 0; i < ans.size(); i++) {
        if (i) putchar(' ');
        printf("%d", ans[i]);
    }
    putchar('\n');
    for (int i = 0; i <= line; i++) {
        printf("%d\n", cnt[i]);
    }
    exit(0);
}

int main(void) {
    char ch = gc();
    int state = START;
    ULL crt;
    while (true) {
        switch (state) {
            case START:
                if (ch >= 'a' && ch <= 'z') {
                    state = ERR;
                } else if (ch == '0') {
                    state = LEAD;
                    realline = line;
                    crt = 0;
                    ch = gc();
                } else if (ch >= '1' && ch <= '9') {
                    state = DIG;
                    realline = line;
                    crt = ch - '0';
                    ch = gc();
                } else if (ch == ' ') {
                    ch = gc();
                } else if (ch == '\n') {
                    ch = gc();
                    line++;
                } else if (ch == EOF) {
                    out();
                }
                break;
            case ERR:
                if (ch >= 'a' && ch <= 'z') {
                    ch = gc();
                } else if (ch >= '0' && ch <= '9') {
                    ch = gc();
                    if (ch == '\n') {
                        line++;
                        ch = gc();
                        if (ch < '0' || ch > '9') state = START;
                    }
                } else if (ch == ' ') {
                    state = START;
                } else if (ch == '\n') {
                    state = START;
                    line++;
                    ch = gc();
                } else if (ch == EOF) {
                    out();
                }
                break;
            case LEAD:
                if (ch >= 'a' && ch <= 'z') {
                    state = ERR;
                } else if (ch >= '0' && ch <= '9') {
                    state = ERR;
                } else if (ch == ' ') {
                    ans.push_back(crt);
                    cnt[realline]++;
                    state = START;
                    ch = gc();
                } else if (ch == '\n') {
                    ch = gc();
                    line++;
                    if (ch >= '0' && ch <= '9') state = ERR;
                    else {
                        ans.push_back(crt);
                        cnt[realline]++;
                        state = START;
                    }
                } else if (ch == EOF) {
                    ans.push_back(crt);
                    cnt[realline]++;
                    out();
                }
                break;
            case DIG:
                if (ch >= 'a' && ch <= 'z') {
                    state = ERR;
                } else if (ch >= '0' && ch <= '9') {
                    crt = crt * 10 + ch - '0';
                    ch = gc();
                } else if (ch == ' ') {
                    state = START;
                    ans.push_back(crt);
                    cnt[realline]++;
                    ch = gc();
                } else if (ch == '\n') {
                    line++;
                    ch = gc();
                    if (ch < '0' || ch > '9') {
                        ans.push_back(crt);
                        cnt[realline]++;
                        state = START;
                    }
                } else if (ch == EOF) {
                    ans.push_back(crt);
                    cnt[realline]++;
                    out();
                }
                break;
        }
    }
    return 0;
}

AC的C++语言程序:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL unsigned long long
#define mod 1000000007
char str[200005];
int ans[1005], id[200005];
LL p[200005];
int main(void)
{
	LL now;
	int n, i, ok, cnt, bel, tot, len;
	len = 1, cnt = tot = 0;
	bel = ok = now = 0;
	while(gets(str+len)!=NULL)
	{
		cnt++;
		n = len-1+strlen(str+len);
		if(len!=1 && (str[len]<'0' || str[len]>'9' || str[len-1]<'0' || str[len-1]>'9'))
		{
			for(i=n;i>=len;i--)
				str[i+1] = str[i];
			str[len] = ' ';
			n++;
		}
		for(i=len;i<=n;i++)
			id[i] = cnt;
		len = n+1;
	}
	str[++n] = ' ';
	for(i=1;i<=n;i++)
	{
		if(str[i]>='1' && str[i]<='9')
		{
			if(ok==1)
				now = now*10+str[i]-'0';
			else	
			{
				if(str[i-1]==' ' || i==1)
				{
					ok = 1, bel = id[i];
					now = str[i]-'0';
				}
			}
		}
		else if(str[i]=='0')
		{
			if(ok==1)
				now = now*10;
			else
			{
				if((str[i-1]==' ' || i==1) && str[i+1]==' ')
				{
					ans[++tot] = 0;
					ans[id[i]]++;
				}
			}
		}
		else if(str[i]==' ')
		{
			if(ok==1)
			{
				p[++tot] = now;
				ans[bel]++;
				now = ok = 0;
			}
		}
		else
		{
			if(ok==1)
				ok = 0, now = 0;
		}
	}
	if(tot>=1)
	{
		printf("%llu", p[1]);
		for(i=2;i<=tot;i++)
			printf(" %llu", p[i]);
	}
	printf("\n");
	for(i=1;i<=cnt;i++)
		printf("%d\n", ans[i]);
	return 0;
}

C. Pythagorean triple


D. Frog and Portal

AC的C++语言程序:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef unsigned int UI;

int main(void) {
    UI n;
    while (~scanf("%d", &n)) {
        vector<pair<int, int>> ans;
        ans.push_back(make_pair(1, 1));
        ans.push_back(make_pair(198, 198));
        ans.push_back(make_pair(197, 197));
        int p = 2;
        while (n > 1) {
            if (n & 1) {
                ans.push_back(make_pair(p + 1, 199));
                ans.push_back(make_pair(p + 5, p + 5));
                p += 6;
            } else {
                ans.push_back(make_pair(p + 3, p + 3));
                p += 4;
            }
            n >>= 1;
        }
        if (n) ans.push_back(make_pair(p, 199));
        printf("%d\n", ans.size());
        for (int i = 0; i < ans.size(); i++)
            printf("%d %d\n", ans[i].first, ans[i].second);
    }
    return 0;
}

AC的C++语言程序:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
LL F[55] = {1,1,2};
int s1[250], s2[250];
int main(void)
{
	LL n;
	int cnt, i, now;
	for(i=3;i<=50;i++)
		F[i] = F[i-1]+F[i-2];
	while(scanf("%lld", &n)!=EOF)
	{
		if(n==0)
			printf("2\n1 1\n2 2\n");
		else if(n==1)
			printf("2\n1 199\n2 2\n");
		else
		{
			now = 1, cnt = 0;
			while(n!=1)
			{
				if(n%2==0)
				{
					s1[++cnt] = now, s2[cnt] = now+2;
					s1[++cnt] = now+1, s2[cnt] = now;
					now += 3;
				}
				else
				{
					s1[++cnt] = now, s2[cnt] = 199;
					now += 2;
					s1[++cnt] = now, s2[cnt] = now+2;
					s1[++cnt] = now+1, s2[cnt] = now;
					now += 3;
				}
				n /= 2;
			}
			s1[++cnt] = now-1, s2[cnt] = 199;
			printf("%d\n", cnt);
			for(i=1;i<=cnt;i++)
				printf("%d %d\n", s1[i], s2[i]);
		}
	}
	return 0;
}

E. Xor 2


F. The Kth Largest Value


G. Solving Equations is Easy


H. Approximate Matching

AC的C++语言程序:

#include <iostream>
#include <vector>
#include <cstring>
#include <queue>
#include <string>

using namespace std;

// 字符集的大小
const int CHARSIZE = 2;
// 自动机状态数上限
const int STATELIM = 1e5;

struct Pattern {
    int id, pos;
    Pattern(int i, int p) : id(i), pos(p) {}
};

// encoding and decoding function
// 根据需要实现字符与编码的映射关系
// 编码应小于CHARSIZE
inline int charToCode(int ch) {
    return ch;
}
inline char codeToChar(int code) {
    return code;
}

class ACauto {
public:
    const int NIL = -1;
    // trie
    int go[STATELIM][CHARSIZE];
    int gblcnt;
    int patcnt;
    // failure index
    int f[STATELIM];
    // end of word flag
    int ef[STATELIM];
    // valid flag: the ac automata has been constructed
    bool vf;
public:
    ACauto() {clear();}
    void clear();
    // insert word to trie
    void insert();
    // build ac automata
    void buildAC();
    // get next state
    int nextState(int, char);
};

void ACauto::clear() {
    vf = false;
    gblcnt = 1;
    patcnt = 0;
    memset(go, NIL, sizeof go);
    memset(ef, 0, sizeof ef);
}
int n, m;
char pat[45];
void ACauto::insert() {
    if (vf)
        for (int i = 0; i < CHARSIZE; i++)
            if (!go[0][i]) go[0][i] = NIL;
    vf = false;
    int crt = 0;
    int pl = n;
    for (int i = 0; i < pl; i++) {
        int key = charToCode(pat[i]);
        if (go[crt][key] == NIL)
            go[crt][key] = gblcnt++;
        crt = go[crt][key];
    }
    ef[crt] |= 1 << (patcnt++);
}

int q[STATELIM];
void ACauto::buildAC() {
    if (vf) return;
    vf = true;
    memset(f, NIL, sizeof f);
    int tail, head;
    head = 0, tail = 1;
    for (int i = 0; i < CHARSIZE; i++) {
        if (go[0][i] == NIL) go[0][i] = 0;
        else {
            f[go[0][i]] = 0;
            q[tail++] = go[0][i];
            if (tail >= STATELIM) tail -= STATELIM;
            // q.push(go[0][i]);
        }
    }
    int crt;
    while (++head != tail) {
        crt = q[head];
        if (head >= STATELIM - 1) head -= STATELIM;
        for (int i = 0; i < CHARSIZE; i++) {
            if (go[crt][i] != NIL) {
                int fail = f[crt];
                while (go[fail][i] == NIL)
                    fail = f[fail];
                fail = go[fail][i];
                f[go[crt][i]] = fail;
                ef[go[crt][i]] |= ef[fail];
                // q.push(go[crt][i]);
                q[tail++] = go[crt][i];
                if (tail >= STATELIM) tail -= STATELIM;
            }
        }
    }
}

int ACauto::nextState(int crt, char key) {
    if (!vf) buildAC();
    int code = charToCode(key);
    while (go[crt][code] == NIL)
        crt = f[crt];
    return go[crt][code];
}

typedef long long LL;

inline char gc() {
    char ret;
    while ((ret = getchar()) == ' ' || ret == '\n' || ret == '\t');
    return ret;
}
ACauto ac = ACauto();
LL dp[2][STATELIM];
int main(void) {
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++)
            pat[i] = gc() - '0';
        ac.clear();
        // build ac automata
        for (int i = 0; i < n; i++) {
            ac.insert();
            pat[i] ^= 1;
            ac.insert();
            pat[i] ^= 1;
        }
        ac.buildAC();
        int t = 0;
        memset(dp[t], 0, sizeof dp[t]);
        dp[t][0] = 1;
        for (int i = 0; i < m; i++) {
            t = 1 - t;
            memset(dp[t], 0, sizeof dp[t]);
            for (int j = 0; j < ac.gblcnt; j++) {
                if (ac.ef[j]) continue;
                for (int k = 0; k < 2; k++) {
                    int ns = ac.nextState(j, k);
                    dp[t][ns] += dp[1 - t][j];
                }
            }
        }
        LL ans = 1ll << m;
        for (int j = 0; j < ac.gblcnt; j++) {
            if (ac.ef[j]) continue;
            ans -= dp[t][j];
        }
        printf("%lld\n", ans);
    }
    return 0;
}

I. Palindromes

AC的C++语言程序:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    string n;
    cin >> t;
    while (t--) {
        cin >> n;
        if (n.size() == 1) {
            cout << (char)(n[0] - 1) << "\n";
        } else if (n[0] == '1') {
            if (n[1] == '0') {
                n[1] = '9';
                for (int i = 1; i < n.size(); i++)
                    cout << n[i];
                for (int i = n.size() - 2; i > 0; i--)
                    cout << n[i];
                cout << '\n';
            } else {
                for (int i = 1; i < n.size(); i++)
                    cout << n[i];
                for (int i = n.size() - 1; i > 0; i--)
                    cout << n[i];
                cout << '\n';
            }
        } else {
            n[0]--;
            for (int i = 0; i < n.size(); i++)
                cout << n[i];
            for (int i = n.size() - 2; i >= 0; i--)
                cout << n[i];
            cout << '\n';
        }
    }
    return 0;
}

AC的C++语言程序:

#include <bits/stdc++.h>
#include <cstring>
#include<string>
using namespace std;
#define ll long long
int main(){
    int T,len;
    string s,t,tt;
    cin>>T;
    while(T--)
    {
        cin>>s;
        len=s.length();
        if(len==1 || s=="11" || s=="10")
        {
            if(s=="11")
                puts("11");
            else if(s=="10")
                puts("9");
            else
                cout<<(char)(s[0]-1)<<endl;
            continue;
        }
        if(s[0]=='1')
        {
            if(s[1]=='0')
            {
                s[1]='9';
                s=s.substr(1,len-1);
                t=s.substr(0,len-2);
                reverse(t.begin(),t.end());
                s+=t;
                cout<<s<<endl;
            }
            else
            {
                s=s.substr(1,len-1);
                t=s;
                reverse(t.begin(),t.end());
                s+=t;
                cout<<s<<endl;
             }
            continue;
        }
        s[0]-=1;
        t=s.substr(0,len-1);
        reverse(t.begin(),t.end());
        s+=t;
        cout<<s<<endl;
    }
    return 0;
}

J. Rikka with Triangles



参考链接:
ABDHI The 2018 ACM-ICPC Asia Beijing Regional Contest

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/89792655