ECNA 2013 部分题解 | 训练记录

提交链接

https://codeforces.com/gym/100291/submit

B . Cuckoo for Hashing [递归]


int n1, n2, m;
int a1[maxn], a2[maxn];
void modify(int f,int val) {
	if(f == 0) {
		if(a1[val % n1] == -1) a1[val % n1] = val;
		else {
			int pre = a1[val % n1];
			a1[val % n1] = val;
			modify(1,pre);
		}
	} else {
		if(a2[val % n2] == -1) a2[val % n2] = val;
		else {
			int pre = a2[val % n2];
			a2[val % n2] = val;
			modify(0,pre);
		}
	}
}
int main() {
    int _ = 0;
    
    while (~scanf("%d%d%d", &n1, &n2, &m) && m) {
        memset(a1, -1, sizeof a1);
        memset(a2, -1, sizeof a2);
        printf("Case %d:\n", ++_);
        for (int i = 1; i <= m; i++) {
  			modify(0,read);
        }
        int c1 = 0,c2 = 0;
        for(int i=0;i<max(n1,n2);i++) {
        	if(a1[i] != -1) c1 ++;
        	if(a2[i] != -1) c2 ++;
        }
        if(c1) {
        	puts("Table 1");
        	for(int i=0; i<n1; i++) {
				if(a1[i] != -1) {
					printf("%d:%d\n",i,a1[i]);
				}
			}
        }
        if(c2) {
        	puts("Table 2");
			for(int i=0; i<n2; i++) {
				if(a2[i] != -1) {
					printf("%d:%d\n",i,a2[i]);
				}
			}
        }
    }
    return 0;
}
/**


**/

C . Playing Fair with Cryptography

队友传送门Code

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;

char a[10][10];
int b[27];
int tx[27],ty[27];

char getNext(char ch,int &idx){
	if(idx==ch-'A') idx=(idx+1)%26;
	if(idx==9) idx++;
	ch=idx+'A';
	idx=(idx+1)%26;
	if(idx==9) idx++;
	return ch;
}

void cul(char u,char v,char &x,char &y){
	int tu=u-'A',tv=v-'A';
	if(tx[tu]==tx[tv]){
		//cout<<"1"<<endl;
		//cout<<tu<<" "<<tx[tu]<<" "<<ty[tu]<<endl;
		//cout<<tv<<" "<<tx[tv]<<" "<<ty[tv]<<endl;
		//cout<<(ty[tu]+1)%5<<"***"<<(ty[tv]+1)%5<<endl;
		x=a[tx[tu]][(ty[tu]+1)%5];
		y=a[tx[tv]][(ty[tv]+1)%5];
		//cout<<x<<" "<<y<<endl;
	}else if(ty[tu]==ty[tv]){
		//cout<<"2"<<endl;
		x=a[(tx[tu]+1)%5][ty[tu]];
		y=a[(tx[tv]+1)%5][ty[tv]];
	}else{
		//cout<<"3"<<endl;
		x=a[tx[tu]][ty[tv]];
		y=a[tx[tv]][ty[tu]];
	}
}

int main(){
    int _,Case=1;cin>>_;
    while(_--){
    	string ss,s="",t="",tt;
    	if(Case==1) getchar();
    	getline(cin,ss);
    	getline(cin,tt);
    //	cout<<ss<<endl;
    //	cout<<tt<<endl;
    	for(int i=0;i<ss.size();i++){
    		if(ss[i]>='a'&&ss[i]<='z'){
    			s+=ss[i]-'a'+'A';
			}
			else if(ss[i]>='A'&&ss[i]<='Z'){
				s+=ss[i];
			}
		}
		for(int i=0;i<tt.size();i++){
			if(tt[i]=='J') tt[i]='I';
			if(tt[i]>='a'&&tt[i]<='z') t+=tt[i]-'a'+'A';
			else if(tt[i]>='A'&&tt[i]<='Z') t+=tt[i];
		}
		//cout<<s<<endl;
		//cout<<t<<endl;
    	int idx=0;
    	memset(b,0,sizeof b);
    	b[9]=1;
    	for(int i=0;i<5;i++)
    		for(int j=0;j<5;j++)
    			a[i][j]='*';
		for(int i=0;i<5;i++){
    		for(int j=0;j<5;j++){
    			while(b[s[idx]-'A']&&idx<s.size()) idx++;
    			if(idx<s.size()){
    				a[i][j]=s[idx],b[s[idx]-'A']=1;
				}
				else break;
			}
		}
		idx=0;
		for(int i=0;i<5;i++)
			for(int j=0;j<5;j++){
				if(a[i][j]!='*') continue;
				while(b[idx]) idx++;
				a[i][j]=idx+'A';
				b[idx]=1;
			}
		for(int i=0;i<5;i++){
			for(int j=0;j<5;j++){
				//cout<<a[i][j]<<" ";
				tx[a[i][j]-'A']=i;
				ty[a[i][j]-'A']=j;
			}
			//cout<<"\n";
		}
		idx=0;
		char x,y;
		string ans="";
		for(int i=0;i<t.size();i+=2){
			if(t[i]==t[i+1]){
				cul(t[i],getNext(t[i],idx),x,y);
				i--;
			}
			else if(i+2>t.size()){
				cul(t[i],getNext(t[i],idx),x,y);
			}
			else cul(t[i],t[i+1],x,y);
			ans=ans+x+y;
		}
		cout<<"Case "<<Case++<<": "<<ans<<endl;
	}
    return 0;
}

F . Super Phyllis

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;

int n,a[1100][1100],Case=0,idx=0;
vector<int>g[1100]; 
map<string,int>mp;
map<int,string>mpp;
bool vis[1100];

void init(){
	idx=0;mp.clear();mpp.clear();
	memset(a,0,sizeof a);
	for(int i=0;i<1100;i++) g[i].clear();
}

int cul(string s){
	if(!mp.count(s)) mp[s]=++idx,mpp[idx]=s;
	return mp[s];
}

bool bfs(int s,int t){
	queue<int>q;
	memset(vis,0,sizeof vis);
	vis[s]=1;q.push(s);
	while(!q.empty()){
		int now=q.front();q.pop();
		if(now==t) return true;
		for(int i=0;i<g[now].size();i++){
			int j=g[now][i];
			if(!a[now][j]) continue;
			if(!vis[j]){
				vis[j]=1;q.push(j);
			}
		}
	}
	return false;
}

int main(){
    while(~scanf("%d",&n)){
    	if(n==0) break;
    	init();
    	for(int i=1;i<=n;i++){
    		string su,sv;
    		cin>>su>>sv;
    		int u=cul(su),v=cul(sv);
    		g[u].push_back(v);
    		a[u][v]=1;
		}
		vector<string>ans;	
		for(int i=1;i<=idx;i++){
			for(int j=0;j<g[i].size();j++){
				int now=g[i][j];
				a[i][now]=0;
				if(!bfs(i,now))
					a[i][now]=1;
				else
					ans.push_back(mpp[i]+","+mpp[now]);
			}
		}
		sort(ans.begin(),ans.end());
		cout<<"Case "<<++Case<<": "<<ans.size();
		for(int i=0;i<ans.size();i++)
			cout<<" "<<ans[i];
		cout<<"\n";
	}
    return 0;
}

H . The Urge to Merge

#include <bits/stdc++.h>

typedef long long ll;

#pragma region Debug
template<typename T>
std::istream& operator>> (std::istream& in, std::vector<T>& vt)
{
	for (auto& i : vt) in >> i;
	return in;
}
template<typename T>
std::ostream& operator<< (std::ostream& out, const std::vector<T>& vt)
{
	for (auto& i : vt) out << i << " ";
	out << std::endl;
	return out;
}
void printAll() {  }
template<typename T1, typename... T2>
void printAll(const T1& first, const T2&... second)
{
	std::cout << first;
	if (sizeof...(second)) {
		std::cout << ", ";
	}
	printAll(second...);
}
template<typename T1, typename... T2>
void print(const T1& first, const T2&... second)
{
	std::cout << "[";
	printAll(first, second...);
	std::cout << "]" << std::endl;
}
#pragma endregion

#define N (int)(5e2 + 10)

int main()
{
	int n;
	while (std::cin >> n && n) {
		static int cas = 1;
		std::vector<std::vector<int>> v(3, std::vector<int>(n)), f(n, std::vector<int>(27));


		for (auto& str : v) {
			for (auto& ch : str) {
				std::cin >> ch;
			}
		}

		/*
		f[i][j] : 1 - i 列所有的数据,最后一列状态为j的最大值
		f[i][j] = max(f[i - 1][k] + val(j))
		*/

		auto judge = [](const std::vector<int>& tmp) {
			for (int i = 0; i < tmp.size() - 1; i++) {
				if (tmp[i] == 1) {
					if (tmp[i + 1] != 1) {
						return false;
					}
					i += 1;
				}
			}
			return true;
		};

		std::vector<std::vector<int>> allSta;
		std::vector<int> allNum;
		for (int i = 0; i < 27; i++) {
			std::vector<int> tmp;
			int num = i;
			while (num) {
				tmp.push_back(num % 3);
				num /= 3;
			}
			while (tmp.size() != 3) tmp.push_back(0);

			std::reverse(tmp.begin(), tmp.end());

			if (judge(tmp)) {
				allSta.push_back(tmp);
				allNum.push_back(i);
			}
		}

		auto calc1 = [&](const std::vector<int>& sta, int col)
		{
			int res = 0;
			for (int i = 0; i < sta.size() - 1; i++) {
				if (sta[i] == 1) {
					res += v[i][col] * v[i + 1][col];
					i += 1;
				}
			}
			return res;
		};

		//print(calc1({ 0,1,1 }, 0));

		for (auto& tmp : allSta) {
			//print(tmp[0], tmp[1], tmp[2]);
		}

		const int& si = allNum.size();
		for (int i = 0; i <= 0; i++) {
			for (int j = 0; j < si; j++) {
				auto& sta = allSta[j];
				auto& num = allNum[j];

				f[i][num] = calc1(sta, i);
			}
		}

		auto judge2 = [](const std::vector<int>& curSta, const std::vector<int>& preSta) {
			for (int i = 0; i < curSta.size(); i++) {
				if (curSta[i] == 2) {
					if (preSta[i] == 1) {
						return false;
					}
					if (preSta[i] == 2) {
						return false;
					}
				}
			}
			return true;
		};

		auto calc2 = [&](const std::vector<int>& curSta, const std::vector<int>& preSta, int col)
		{
			int res = 0;
			for (int i = 0; i < curSta.size() - 1; i++) {
				if (curSta[i] == 1) {
					res += v[i][col] * v[i + 1][col];
					i += 1;
				}
				else if (curSta[i] == 2) {
					res += v[i][col] * v[i][col - 1];
				}
			}
			if (curSta[curSta.size() - 1] == 2) {
				res += v[curSta.size() - 1][col] * v[curSta.size() - 1][col - 1];
			}
			return res;
		};

		/*
		0 : 先不合并
		1 : 上下合并
		2 : 突出
		*/

		int mx = 0;
		for (int i = 1; i < n; i++) {
			for (int j = 0; j < si; j++) {
				auto& curSta = allSta[j];
				auto& curNum = allNum[j];

				for (int k = 0; k < si; k++) {
					auto& preSta = allSta[k];
					auto& preNum = allNum[k];

					if (judge2(curSta, preSta)) {
						f[i][curNum] = std::max(f[i][curNum], f[i - 1][preNum] + calc2(curSta, preSta, i));
					}
				}
				if (i == n - 1) {
					mx = std::max(mx, f[i][curNum]);
				}
			}
		}

		printf("Case %d: %d\n", cas++, mx);
		//std::cout << f[0][4] << std::endl;
	}
	return 0;
}

I . Xenospeak [规律模拟]

其中,num[i]表示长度为i的字符串有多少个
然后确定了字符串的长度进行构造
如果说前一个为a开头的,那么说后面可以拼接任意的字符串,转移到len-1的情况
如果说是b开头的,只能是bb并且转移到len-2的情况
根据规律进行模拟

ll num[1007];
string get(ll a) {
    int len = 1;
    while (num[len] < a) a -= num[len],len++;
    string s;
    s.clear();
    int fa   = 0;
    for (int i = len; i >= 1; i--) {
    	ll need = num[i-1];/// 看两位,注意没有两位的情况,比如当前i为1
    	if(i > 1) need += num[i-2];
    	if(need >= a) s.push_back('a'),fa = 1;
    	else {
    		if(fa == 0) {
    			s.push_back('b');
    			s.push_back('b');
    			a -= need;
    			-- i;/// 加了两个需要再减去一个长度
    		}else {
    			s.push_back('b');
    			a -= need;
    		}
    	}
    }
    return s;
}
int main() {
    num[0] = num[1] = 1;
    for (int i = 2; i <= 1000; i++) num[i] = num[i - 1] + num[i - 2] + num[i - 2];
    ll n, m;
    int _ = 0;
    while (cin >> n >> m && (n || m)) {
        printf("Case %d: %s %s\n", ++_, get(n * (m - 1) + 1).c_str(), get(n * m).c_str());
    }
    return 0;
}
/**


**/

E . Stampede! [二分 + 网络最大流(拆点)]

没有技巧,全是感情
可以参考:博客1 博客2
提交链接
Code:

/*** keep hungry and calm PushyTao!***/
#pragma GCC optimize(2)
#pragma G++ optimize(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll inf   = 9223372036854775807;
const ll INF   = 0x3f3f3f3f;
const int maxn = 1e6 + 7000;

struct Edge {
    int u, v;
    ll cap, flow;
    Edge(int _u, int _v, ll _cap, ll _flow) {
        u = _u, v = _v;
        cap = _cap, flow = _flow;
    }
};
struct Dinic {
    vector<Edge> edge;
    vector<int> G[maxn << 1];
    ll dis[maxn << 1], cur[maxn << 1];
    int n, s, t;
    bool vis[maxn << 1];
    void init(int x, int _s, int _t) {
        n = x;
        for (int i = 0; i <= n; i++) G[i].clear();
        s = _s, t = _t;
        edge.clear();
    }
    void add(int u, int v, ll cap) {
        edge.push_back(Edge(u, v, cap, 0));
        edge.push_back(Edge(v, u, 0, 0));
        G[u].push_back(edge.size() - 2);
        G[v].push_back(edge.size() - 1);
    }
    bool bfs(int s, int t) {
        queue<int> que;
        memset(vis, 0, sizeof vis);
        // memset(dis,0,sizeof dis);
        dis[s] = 0;
        que.push(s);
        vis[s] = 1;
        while (que.size()) {
            int u = que.front();
            que.pop();
            for (int i = 0; i < (int)G[u].size(); i++) {
                int id = G[u][i];
                int to = edge[id].v;
                if (!vis[to] && edge[id].cap > edge[id].flow) {
                    dis[to] = dis[u] + 1;
                    que.push(to);
                    vis[to] = 1;
                }
            }
        }
        return vis[t];
    }
    ll dfs(int s, int t, ll rest) {
        if (s == t || rest == 0) return rest;
        ll Flow = 0, f;
        for (ll &i = cur[s]; i < G[s].size(); i++) {
            Edge &e = edge[G[s][i]];
            if (dis[s] + 1 == dis[e.v] && (f = dfs(e.v, t, min(rest, e.cap - e.flow))) > 0) {
                e.flow += f;
                edge[G[s][i] ^ 1].flow -= f;
                Flow += f;
                rest -= f;
                if (rest == 0) break;
            }
        }
        return Flow;
    }
    ll getMaxFlow(int s, int t) {
        ll ans = 0;
        while (bfs(s, t)) {
            memset(cur, 0, sizeof cur);
            ans += dfs(s, t, 0x3f3f3f3f);
        }
        return ans;
    }
} solve;
int n;
string s[maxn];
int getId(int x, int y, int f) {
    return x * n + y + 1 + f * n * n;
}
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
bool in(int x, int y) {
    if (x >= 0 && x <= n - 1 && y >= 0 && y <= n - 1 && s[x][y] == '.') return true;
    return false;
}
bool check(int v) {
    int st = 0, ed = n * n * (v + 1) + 1;
    solve.init(1000001, st, ed);
    for (int i = 0; i < n; i++) {
        solve.add(st, getId(i, 0, 0), 1);
        solve.add(getId(i, n - 1, v), ed, 1);
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (s[i][j] == '.') {
                for (int k = 0; k < v; k++) {
                    solve.add(getId(i, j, k), getId(i, j, k + 1), 1);
                    for (int t = 0; t < 4; t++) {
                        int tox = i + dx[t];
                        int toy = j + dy[t];
                        if (in(tox, toy)) {
                            solve.add(getId(i, j, k), getId(tox, toy, k + 1), 1);
                        }
                    }
                }
            }
        }
    }
    return solve.getMaxFlow(st, ed) == n;
}
int main() {
    int _ = 0;
    while (cin >> n && n) {
        for (int i = 0; i < n; i++) cin >> s[i];
        int l = 0, r = n * n + 10;
        int ans = 0;
        while (l < r) {
            int mid = ((l + r) >> 1);
            if (check(mid)) ans = mid, r = mid;
            else l = mid + 1;
        }
        printf("Case %d: %d\n", ++_, ans);
    }
    return 0;
}
posted @ 2022-07-08 00:43  PushyTao  阅读(21)  评论(0编辑  收藏  举报  来源