zoukankan      html  css  js  c++  java
  • 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
    ", 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;
    }
    
  • 相关阅读:
    nginx预防常见攻击
    nginx性能优化(针对于高并发量仅供参考,并不是方案)
    nginx平滑升级(1.14--1.15)
    LAMP动静分离安装(源码安装)
    洛谷-P1098 字符串的展开
    洛谷-P1086 花生采摘
    洛谷-P1042 乒乓球
    洛谷-P1031 均分纸牌
    洛谷-P1023 税收与补贴问题
    洛谷-P1125 笨小猴
  • 原文地址:https://www.cnblogs.com/spbv587/p/11656389.html
Copyright © 2011-2022 走看看