10.11 模拟赛(QBXT国庆Day3)

DAY 3 QBXT

T1

像个SB题, 不过出了点小锅;

我的思路就是 把一个字符串的答案字符串的长度赋成\(len-1\), 然后每一位都赋成\(a\);

记录一个\(add(len)\) 表示先前出现过多少长度为\(len\) 的不同字符串;

处理当前字符串时, 先从map里扒, 扒不到就把他的答案赋为\(len-1个a\), 然后再加上\(add(len)\);

(在考场上没想到把\(add(len)\) 变为26进制分别加)。。。。。

给的正解是无损压缩(没错我也没听说过);

就是把所有的字符串sort一遍挨个赋\(a, b, c, d, e.....\),

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#define ull unsigned long long
const ull base = 2333;
using namespace std;
map<ull , int> mp;
int n, id;
struct node
{
	char a[55], ans[55];
	int len, id;
}e[1005];
int add[55];
void solve(int x)
{
	ull res = 0;
	for(int i = 1; i <= e[x].len; i ++)
		res = res * base + e[x].a[i];	
	if(mp.find(res) != mp.end())
	{
	   id = mp[res]; 
       int len = e[x].len - 1;
       for(int i = 1; i <= len; i ++)
	   e[x].ans[i] = e[id].ans[i];
	}
	else
	{
		mp[res] = x;
		int len = e[x].len - 1;
        for(int i = 1; i <= len; i ++)
	      e[x].ans[i] = 'a';
	    int cc = add[len], t = 1;
	    while(cc)
	    {
	    	e[x].ans[t] += cc % 26;//emm按26进制算 
	    	cc /= 26;
	    	t ++;
	    }
	    add[len] ++;
	}
}
signed main()
{
	freopen("url.in", "r", stdin);
	freopen("url.out", "w", stdout);
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++)
	{
		scanf("%s", e[i].a + 1);
		e[i].len = strlen(e[i].a + 1);
		e[i].id = i;
	}
	for(int i = 1; i <= n; i ++)
		solve(i);
	for(int i = 1; i <= n; i ++)
	{
		printf("%s\n", e[i].ans + 1);
	}
	return 0;
}

T2

当场切掉这个题

把所有的信息读进来后, 记录一下入度;

正常情况下ta是一个根入度为0, 其他入度为1的有向树;

扫一下所有点的入度:

1.找到一个入度为0的点;

​ 此时这个点一定是根(废话)

​ 此时一定对应着某个点的入度为2,找出来那个点和那两个入度边, 枚举删掉哪一个,

然后dfs一遍树, 看成不成立即可

2 .未找到入度为0的点;

也就是没有固定的根, 此时一定有一个环(稍微想一想)

​ 然后把这个环找出来, 然后枚举删掉环上哪一条边 以这条边的to为根dfs判断成不成立即可即可;

成立条件 : 能从根遍利到所有点, 且无环;

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
using namespace std;
struct node
{
	int u, v, nxt;
}e[100005];
int flag, head[100005], cnt, a, b, n, du[100005], uu, vv, ans, tot;
bool vis[100005];
void add(int x, int y)
{
	e[++cnt].u = x;
	e[cnt].v = y;
	e[cnt].nxt = head[x];
	head[x] = cnt;
}
struct edge
{
	int u, v;
}ee[100005];
void dfs(int x)
{
	tot ++;
	if(flag == 1) return ;
	vis[x] = 1;
	for(int i = head[x];i ; i = e[i].nxt)
	{
		int to = e[i].v;
		if(x == uu && to == vv) continue;
		if(vis[to])
		{
			flag = 1;
			return ;
		} 
		dfs(to);
	}
}
signed main()
{
	freopen("remove.in", "r", stdin);
	freopen("remove.out", "w", stdout);
	scanf("%d" ,&n);
	for(int i = 1; i <= n; i ++)
	{
		scanf("%d%d", &a, &b);
		add(a, b);
		ee[i].u = a, ee[i].v = b;
		du[b] ++;
	}
	int rt = 0;
	for(int i = 1; i <= n; i ++)
		if(du[i] == 0) rt = i; 
	if(rt != 0)
	{
		for(int i = n; i >= 1; i --)
		{
			if(du[ee[i].v] != 2) continue;
			else
			{
				for(int j = 1; j <= n; j ++) vis[j] = 0;
				uu = ee[i].u; vv = ee[i].v;
				flag = 0; tot = 0; dfs(rt);
				if(!flag&&tot == n)
				{
					ans = i;break;
				} 
			}	
		}
	}
	else
	{
		for(int i = n; i >= 1; i --)
		{
			for(int j = 1; j <= n; j ++) vis[j] = 0;
			uu = ee[i].u; vv = ee[i].v;
			flag = 0; tot = 0; dfs(ee[i].v);
			if(!flag&&tot == n)
			{
				ans = i;break;
			} 
		}
	}
	printf("%d", ans);
    return 0;
}

T3

啥都别说概率Dp

易得k没啥用

so, n = n/k 上取整, k = 1;

\(f(i, j)\)表示A 还有\(i\), 吨未倒, B还有\(j\)吨未倒时的答案(概率);

\(f(i, 0)=0.0\) \(f(0, j)=1.0\) \(f(0, 0) = 0.5\)

\(f(i, j) = (f(i-1, j-3)+f(i-2, j-2)+f(i-3,j-1)+f(i-4,j))*0.25\)

\(f(n, n)\) 就是答案;

由打表易得当\(n > 235\)\(ans = 1.0\) 所以不用怕dp数组空间复杂度

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
using namespace std;
int n, k, o;
double f[10000][10100];
signed main()
{
	freopen("tea.in", "r", stdin);
	freopen("tea.out", "w", stdout);
	scanf("%d%d", &n, &k);
	if(n%k!=0) o = 1;
	n /= k; n += o;
	if(n >= 235) {printf("1.000000"); return 0;}
	f[0][0] = 0.5;
	for(int i = 1; i <= n; i ++)
	   f[i][0] = 0.0;
	for(int i = 1; i <= n; i ++)
	   f[0][i] = 1.0;
	for(int i = 1; i <= n; i ++)
	   for(int j = 1; j <= n; j ++)
	   f[i][j] = 0.25 * (f[max(i-1, 0)][max(j-3, 0)] + f[max(i-2, 0)][max(j-2, 0)] + f[max(i-3, 0)][max(j-1, 0)] + f[max(i-4, 0)][j]);
    printf("%.6f", f[n][n]);		
    return 0;
}
posted @ 2019-10-11 19:40  spbv587  阅读(107)  评论(0编辑  收藏  举报