GRYZ20211105模拟赛解题报告

目录

期望得分:(100+100+100=300pts)
实际得分:(100+80+100=280pts)

Journey Of my Heart when testing

T1

先把字符串长度排序,再按照字典序排序,然后从前往后赋值,可以相当于离散化一下,然后按照 a,b,c,...,z,aa,ab,ac,... 这个顺序依次填就可以。

转化成 26 进制好像有点麻烦的感觉,发现 (n le 1000),打个表就行了。保证有解也不需要管其他东西。

/*
Work by: Suzt_ilymtics
Problem: 不知名屑题
Knowledge: 垃圾算法
Time: O(能过)
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<string>
#define LL long long
#define orz cout<<"lkp AK IOI!"<<endl

using namespace std;
const int MAXN = 1e5+5;
const int INF = 1e9+7;
const int mod = 1e9+7;

string biao[1010] = {"0","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
"aa","ab","ac","ad","ae","af","ag","ah","ai","aj","ak","al","am","an","ao","ap","aq","ar","as","at","au","av","aw","ax","ay","az",
"ba","bb","bc","bd","be","bf","bg","bh","bi","bj","bk","bl","bm","bn","bo","bp","bq","br","bs","bt","bu","bv","bw","bx","by","bz",
"ca","cb","cc","cd","ce","cf","cg","ch","ci","cj","ck","cl","cm","cn","co","cp","cq","cr","cs","ct","cu","cv","cw","cx","cy","cz",
"da","db","dc","dd","de","df","dg","dh","di","dj","dk","dl","dm","dn","do","dp","dq","dr","ds","dt","du","dv","dw","dx","dy","dz",
"ea","eb","ec","ed","ee","ef","eg","eh","ei","ej","ek","el","em","en","eo","ep","eq","er","es","et","eu","ev","ew","ex","ey","ez",
"fa","fb","fc","fd","fe","ff","fg","fh","fi","fj","fk","fl","fm","fn","fo","fp","fq","fr","fs","ft","fu","fv","fw","fx","fy","fz",
"ga","gb","gc","gd","ge","gf","gg","gh","gi","gj","gk","gl","gm","gn","go","gp","gq","gr","gs","gt","gu","gv","gw","gx","gy","gz",
"ha","hb","hc","hd","he","hf","hg","hh","hi","hj","hk","hl","hm","hn","ho","hp","hq","hr","hs","ht","hu","hv","hw","hx","hy","hz",
"ia","ib","ic","id","ie","if","ig","ih","ii","ij","ik","il","im","in","io","ip","iq","ir","is","it","iu","iv","iw","ix","iy","iz",
"ja","jb","jc","jd","je","jf","jg","jh","ji","jj","jk","jl","jm","jn","jo","jp","jq","jr","js","jt","ju","jv","jw","jx","jy","jz",
"ka","kb","kc","kd","ke","kf","kg","kh","ki","kj","kk","kl","km","kn","ko","kp","kq","kr","ks","kt","ku","kv","kw","kx","ky","kz",
"la","lb","lc","ld","le","lf","lg","lh","li","lj","lk","ll","lm","ln","lo","lp","lq","lr","ls","lt","lu","lv","lw","lx","ly","lz",
"ma","mb","mc","md","me","mf","mg","mh","mi","mj","mk","ml","mm","mn","mo","mp","mq","mr","ms","mt","mu","mv","mw","mx","my","mz",
"na","nb","nc","nd","ne","nf","ng","nh","ni","nj","nk","nl","nm","nn","no","np","nq","nr","ns","nt","nu","nv","nw","nx","ny","nz",
"oa","ob","oc","od","oe","of","og","oh","oi","oj","ok","ol","om","on","oo","op","oq","or","os","ot","ou","ov","ow","ox","oy","oz",
"pa","pb","pc","pd","pe","pf","pg","ph","pi","pj","pk","pl","pm","pn","po","pp","pq","pr","ps","pt","pu","pv","pw","px","py","pz",
"qa","qb","qc","qd","qe","qf","qg","qh","qi","qj","qk","ql","qm","qn","qo","qp","qq","qr","qs","qt","qu","qv","qw","qx","qy","qz",
"ra","rb","rc","rd","re","rf","rg","rh","ri","rj","rk","rl","rm","rn","ro","rp","rq","rr","rs","rt","ru","rv","rw","rx","ry","rz",
"sa","sb","sc","sd","se","sf","sg","sh","si","sj","sk","sl","sm","sn","so","sp","sq","sr","ss","st","su","sv","sw","sx","sy","sz",
"ta","tb","tc","td","te","tf","tg","th","ti","tj","tk","tl","tm","tn","to","tp","tq","tr","ts","tt","tu","tv","tw","tx","ty","tz",
"ua","ub","uc","ud","ue","uf","ug","uh","ui","uj","uk","ul","um","un","uo","up","uq","ur","us","ut","uu","uv","uw","ux","uy","uz",
"va","vb","vc","vd","ve","vf","vg","vh","vi","vj","vk","vl","vm","vn","vo","vp","vq","vr","vs","vt","vu","vv","vw","vx","vy","vz",
"wa","wb","wc","wd","we","wf","wg","wh","wi","wj","wk","wl","wm","wn","wo","wp","wq","wr","ws","wt","wu","wv","ww","wx","wy","wz",
"xa","xb","xc","xd","xe","xf","xg","xh","xi","xj","xk","xl","xm","xn","xo","xp","xq","xr","xs","xt","xu","xv","xw","xx","xy","xz",
"ya","yb","yc","yd","ye","yf","yg","yh","yi","yj","yk","yl","ym","yn","yo","yp","yq","yr","ys","yt","yu","yv","yw","yx","yy","yz",
"za","zb","zc","zd","ze","zf","zg","zh","zi","zj","zk","zl","zm","zn","zo","zp","zq","zr","zs","zt","zu","zv","zw","zx","zy","zz",
"aaa","aab","aac","aad","aae","aaf","aag","aah","aai","aaj","aak","aal","aam","aan","aao","aap","aaq","aar","aas","aat","aau","aav","aaw","aax","aay","aaz",
"aba","abb","abc","abd","abe","abf","abg","abh","abi","abj","abk","abl","abm","abn","abo","abp","abq","abr","abs","abt","abu","abv","abw","abx","aby","abz",
"aca","acb","acc","acd","ace","acf","acg","ach","aci","acj","ack","acl","acm","acn","aco","acp","acq","acr","acs","act","acu","acv","acw","acx","acy","acz",
"ada","adb","adc","add","ade","adf","adg","adh","adi","adj","adk","adl","adm","adn","ado","adp","adq","adr","ads","adt","adu","adv","adw","adx","ady","adz",
"aea","aeb","aec","aed","aee","aef","aeg","aeh","aei","aej","aek","ael","aem","aen","aeo","aep","aeq","aer","aes","aet","aeu","aev","aew","aex","aey","aez",
"afa","afb","afc","afd","afe","aff","afg","afh","afi","afj","afk","afl","afm","afn","afo","afp","afq","afr","afs","aft","afu","afv","afw","afx","afy","afz",
"aga","agb","agc","agd","age","agf","agg","agh","agi","agj","agk","agl","agm","agn","ago","agp","agq","agr","ags","agt","agu","agv","agw","agx","agy","agz",
"aha","ahb","ahc","ahd","ahe","ahf","ahg","ahh","ahi","ahj","ahk","ahl","ahm","ahn","aho","ahp","ahq","ahr","ahs","aht","ahu","ahv","ahw","ahx","ahy","ahz",
"aia","aib","aic","aid","aie","aif","aig","aih","aii","aij","aik","ail","aim","ain","aio","aip","aiq","air","ais","ait","aiu","aiv","aiw","aix","aiy","aiz",
"aja","ajb","ajc","ajd","aje","ajf","ajg","ajh","aji","ajj","ajk","ajl","ajm","ajn","ajo","ajp","ajq","ajr","ajs","ajt","aju","ajv","ajw","ajx","ajy","ajz",
"aka","akb","akc","akd","ake","akf","akg","akh","aki","akj","akk","akl","akm","akn","ako","akp","akq","akr","aks","akt","aku","akv","akw","akx","aky","akz",
"ala","alb","alc","ald","ale","alf","alg","alh","ali","alj","alk","all"};

struct node {
    string s;
    int id;
    bool operator < (const node &b) const {
        int len1 = s.length(), len2 = b.s.length();
        if(len1 != len2) return len1 < len2;
        for(int i = 0; i < len1; ++i) {
            if(s[i] < b.s[i]) return true;
            if(s[i] > b.s[i]) return false;
        }
        return false;
    }
}a[1010];

int n, Cnt = 0;
int ans[1010];
int stc[1010], sc = 0;

int read(){
    int s = 0, f = 0;
    char ch = getchar();
    while(!isdigit(ch))  f |= (ch == '-'), ch = getchar();
    while(isdigit(ch)) s = (s << 1) + (s << 3) + ch - '0' , ch = getchar();
    return f ? -s : s;
}

int main()
{
    freopen("url.in","r",stdin);
    freopen("url.out","w",stdout); 
	n = read();
	for(int i = 1; i <= n; ++i) cin >> a[i].s, a[i].id = i;
    sort(a + 1, a + n + 1);
    for(int i = 1; i <= n; ++i) {
        if(a[i].s != a[i - 1].s) ans[a[i].id] = ++ Cnt;
        else ans[a[i].id] = Cnt;
    }
    for(int i = 1; i <= n; ++i) cout<<biao[ans[i]]<<"
";
    return 0;
}

T2

(n) 个点 (n) 条边,只会有一个环。

因为保证有解那有向图下环的状态只有两种:

1、环是环:没有入度为 0 的点,就从环上找一个边最大的删。如果有入度为 0 的点,就找出环上入度为 2 的点,把连向该点的一条在环上的边删掉。我赛时没考虑第二种情况,然后被卡了。/kk

2、环不是环:只有两条指向了一个入度为 (2) 的点的边才可以选,对这两条边取个 (max)

我比较菜,我采用先搞一个生成树,然后第 (n) 条边的两个端点沿着树向上爬,找出那个环来在进行统计。

时间复杂度 (mathcal O(n))

我的实现挺傻逼的感觉。

/*
Work by: Suzt_ilymtics
Problem: 不知名屑题
Knowledge: 垃圾算法
Time: O(能过)
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
#define orz cout<<"lkp AK IOI!"<<endl

using namespace std;
const int MAXN = 2e5+5;
const int INF = 1e9+7;
const int mod = 1e9+7;

struct edge { int to, w, nxt; }e[MAXN << 1];
int head[MAXN], num_edge = 1;

struct node { int u, v; }E[MAXN];

int n, ans;
int val[MAXN];
int ind[MAXN], oud[MAXN];
int dep[MAXN], fath[MAXN], fa[MAXN];
int stc[MAXN], sc = 0;
bool flag[MAXN];

int read(){
    int s = 0, f = 0;
    char ch = getchar();
    while(!isdigit(ch))  f |= (ch == '-'), ch = getchar();
    while(isdigit(ch)) s = (s << 1) + (s << 3) + ch - '0' , ch = getchar();
    return f ? -s : s;
}

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); } 
void add_edge(int from, int to, int w) { e[++num_edge] = (edge){to, w, head[from]}, head[from] = num_edge; }

void dfs(int u, int fa) {
    dep[u] = dep[fa] + 1, fath[u] = fa;
    for(int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if(v == fa) continue;
        val[v] = e[i].w;
        dfs(v, u);
    }
}

void Get() {
    int u = E[stc[sc]].u, v = E[stc[sc]].v;
    while(u != v) {
        if(dep[u] < dep[v]) swap(u, v);
        stc[++sc] = val[u];
        u = fath[u];
    }
    return ;
}

int main()
{
//    freopen("remove.in","r",stdin);
//    freopen("remove.out","w",stdout);
	n = read();
	for(int i = 1; i <= n; ++i) fa[i] = i;
	for(int i = 1, uf, vf; i <= n; ++i) {
	    E[i].u = read(), E[i].v = read();
	    if(E[i].u == E[i].v) {
	        printf("%d
", i);
	        return 0;
        }
	    uf = find(E[i].u), vf = find(E[i].v);
	    if(uf != vf) {
	        fa[uf] = vf;
	        add_edge(E[i].u, E[i].v, i), add_edge(E[i].v, E[i].u, i);
        } else {
            stc[++sc] = i;
        }
    }
    dfs(1, 0);
    Get();
    for(int i = 1; i <= sc; ++i) {
        ind[E[stc[i]].v] ++, oud[E[stc[i]].u]++;
        flag[E[stc[i]].u] = true, flag[E[stc[i]].v] = true;
    }
    bool Flag = false;
    for(int i = 1; i <= n; ++i) {
        if(!flag[i]) continue;
        if(!ind[i] || ind[i] == 2) Flag = true;
    }
//    cout<<Flag<<" "<<sc<<"
";
    if(Flag) {
        for(int i = 1; i <= sc; ++i) {
            if(ind[E[stc[i]].v] == 2) {
                ans = max(ans, stc[i]);
            }
        }
    }
    else {
        memset(ind, false, sizeof ind);
        memset(oud, false, sizeof oud);
        for(int i = 1; i <= n; ++i) {
            ind[E[i].v]++, oud[E[i].u]++;
        }
        int Fan_Tuan = 0;
        for(int i = 1; i <= n; ++i) {
            if(ind[i] == 2) Fan_Tuan = i;
        }
        if(Fan_Tuan) {
            for(int i = 1; i <= sc; ++i) {
                if(E[stc[i]].v == Fan_Tuan) {
                    ans = max(ans, stc[i]);
                }
            }
        } else {
            for(int i = 1; i <= sc; ++i) ans = max(ans, stc[i]);
        }
    }
    printf("%d
", ans);
    return 0;
}

T3

看到 (60\%) 的数据范围,感觉可以 DP 做,然后就设 (f{i,j}) 表示 A 剩下 (i) 吨, B 剩下 (j) 吨的概率。然后 DP 就好了。

具体转移的时候我在纠结一个事,假设 A 倒 (K)吨,但 A 只有 (x) 吨((x < k)),那 B 应该倒 (3K) 吨还是 (4K - x) 吨呢?

感觉题意说的不明确。

通过实验发现,前面是正确的。(如果采用后面的方式,跑不出样例来)。

然后你看到了 (K=1) 的部分分,你打算随便试几个数找找规律,你发现当 (n ge 235) 的时候,答案为 (1.000000),你感觉很不可思议,检查了一下代码没有问题,那这就是结论了,当 (n) 较大,(K=1) 的时候答案就是 (1.000000)

你在考虑正解,你发现对于一对 (n,K),最多能取的次数是一定的,我们设 (ans(n,K)) 表示这个状态下的答案,然后我们猜一个结论。

[ans(n,K) = ans(frac{n-1}{K}+1, 1) ]

然后你写了一个对拍,拍了上千组数据后发现没什么问题。

那这样 (K != 1) 的情况能转化成 (K=1) 的情况,那这题做完了。

/*
Work by: Suzt_ilymtics
Problem: 不知名屑题
Knowledge: 垃圾算法
Time: O(能过)
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
#define orz cout<<"lkp AK IOI!"<<endl

using namespace std;
const int MAXN = 1e5+5;
const int INF = 1e9+7;
const int mod = 1e9+7;

int n, K;
double f[1010][1010], ans = 0;

int read() {
    int s = 0, f = 0;
    char ch = getchar();
    while(!isdigit(ch)) f |= (ch == '-'), ch = getchar();
    while(isdigit(ch)) s = (s << 1) + (s << 3) + ch - '0', ch = getchar();
    return f ? -s : s;
}

int main()
{
    freopen("tea.in","r",stdin);
    freopen("tea.out","w",stdout);
	n = read(), K = read();
	n = (n - 1) / K + 1, K = 1; // 向上取整 
	if(n >= 1000) {
	    puts("1.000000");
	    return 0;
    }
	f[n][n] = 1.0;
	for(int i = n; i >= 1; --i) {
	    for(int j = n; j >= 1; --j) {
	        for(int k = 1; k <= 4; ++k) {
	            f[max(0, i - k * K)][max(0, j - (4 - k) * K)] += f[i][j] / 4.0;
            }
        }
    }
    for(int i = 1; i <= n; ++i) ans = ans + f[0][i];
    ans = ans + f[0][0] / 2.0;
    printf("%.6lf
", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/Silymtics/p/test-GRYZ20211105.html