10.11 模拟赛(QBXT国庆Day3)

六眼飞鱼酱① 提交于 2019-12-01 04:58:47

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 > 某个数 时 \(ans = 1.0\)

#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 >= 200) {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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!