2019 牛客多校第五场 7/10

本文深入探讨了多项算法竞赛题目,包括数位DP、矩阵快速幂、mask DP、图论、独立集、最大匹配等核心算法的应用与实现细节,通过具体实例解析了各种算法的高效解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第四场咕咕咕了,有空补

A

考虑构造的话就是把n看成一个字符串然后重复n次,考虑数位DP的话就爆搞就行,题解里面说求最小的话就记录一下这个状态的最小位数,以及当前位最小填的是什么,然后暴力往回搜就行

/* ***********************************************
Author        :BPM136
Created Time  :2019/8/1 12:01:25
File Name     :A.cpp
************************************************ */
 
#include <bits/stdc++.h>
#include <sys/timeb.h>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define USE_CIN_COUT ios::sync_with_stdio(0)
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define mkd(x) freopen(#x".in","w",stdout);
 
using namespace std;
 
int random(int l, int r) {
    static std::random_device rd;
    struct timeb timeSeed;
    ftime(&timeSeed);
    size_t seed = timeSeed.time * 1000 + timeSeed.millitm;  // milli time
    static std::mt19937 gen(seed);
    std::uniform_int_distribution<> u(l, r);
    return u(gen);
}
 
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;
typedef pair<int, int> pii;
 
bool f[101][100][100];
int now[101][100][100];
pii pre[101][100][100];
 
void dfs(int x, int y, int z) {
    if (x == 0)
        return;
    dfs(x - 1, pre[x][y][z].first, pre[x][y][z].second);
    cout << now[x][y][z];
}
 
int main() {
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        memset(f, 0, sizeof(f));
        for (int i = 1; i <= 9; ++i) {
            f[1][i % n][i % n] = 1;
            now[1][i % n][i % n] = i;
            pre[1][i % n][i % n] = { 0, 0 };
        }
        int ans = 0;
        for (int i = 1; i <= 10000; ++i) {
            for (int j = 0; j < n; ++j)
                for (int k = 0; k < n; ++k)
                    if (f[i][j][k] == 1)
                        for (int p = 0; p <= 9; ++p) {
                            f[i + 1][(j * 10 + p) % n][(k + p) % n] = 1;
                            now[i + 1][(j * 10 + p) % n][(k + p) % n] = p;
                            pre[i + 1][(j * 10 + p) % n][(k + p) % n] = { j, k };
                        }
            if (f[i][0][0]) {
                ans = i;
                break;
            }
        }
        if (ans == 0)
            cout << "Impossible";
        else
            dfs(ans, 0, 0);
        cout << '\n';
    }
    return 0;
}

B

对不起我没想到10进制快速幂,有空补
补了一下

/* ***********************************************
Author        :BPM136
Created Time  :2019/8/5 16:04:55
File Name     :B.cpp
************************************************ */

#include <bits/stdc++.h>
#include <sys/timeb.h>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define USE_CIN_COUT ios::sync_with_stdio(0)
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define mkd(x) freopen(#x".in","w",stdout);

using namespace std;

int random(int l, int r) {
	static std::random_device rd;
	struct timeb timeSeed;
	ftime(&timeSeed);
	size_t seed = timeSeed.time * 1000 + timeSeed.millitm;  // milli time
	static std::mt19937 gen(seed);
	std::uniform_int_distribution<> u(l, r);
	return u(gen);
}

typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;
typedef pair<int, int> pii;

ll mod;

struct matrix {
	int a[2][2];

	matrix() {
		memset(a, 0, sizeof(a));
	}

	matrix(int _a, int b, int c, int d) {
		a[0][0] = _a;
		a[0][1] = b;
		a[1][0] = c;
		a[1][1] = d;
	}

	matrix operator * (matrix const& b) const {
		matrix ret;
		for (int i = 0; i < 2; ++i) 
			for (int j = 0; j < 2; ++j) 
				ret.a[i][j] = ((ll) a[i][0] * b.a[0][j] % mod + (ll) a[i][1] * b.a[1][j] % mod) % mod;
		return ret;
	}

	void out() {
		for (int i = 0; i < 2; ++i) {
			for (int j = 0; j < 2; ++j)
				cout << a[i][j] << ' ';
			cout << '\n';
		}
	}
};

matrix I = {
	1, 0,
	0, 1
};

matrix KSM(matrix a, int k) {
	auto ret = I;
	for (; k; k >>= 1, a = a * a)
		if (k & 1)
			ret = ret * a;
	return ret;
}

string n;

matrix KSM_bit10(matrix a) {
	auto ret = I;
	for (int i = SZ(n) - 1; i >= 0; --i) {
		if (n[i] != '0') 
			ret = ret * KSM(a, n[i] - '0');
		a = KSM(a, 10);
	}
	return ret;
}

int main() {
	USE_CIN_COUT;
	auto A = matrix(), T = matrix();
	cin >> A.a[0][0] >> A.a[0][1] >> T.a[1][1] >> T.a[0][1];
	T.a[1][0] = 1;
	cin >> n >> mod;
	auto ans = A * KSM_bit10(T);
	cout << ans.a[0][0] << '\n';
    return 0;
}

C

D

E

傻叉mask DP,居然没多少人做,根据独立集的性质就可以得到转移方程,每次考虑加入一个点就行,然后考虑这个点是否成为独立集中的一个就行。不小心抢到了首杀真是抱歉XD

/* ***********************************************
Author        :BPM136
Created Time  :2019/8/1 13:02:58
File Name     :E.cpp
************************************************ */
 
#include <bits/stdc++.h>
#include <sys/timeb.h>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define mkdfile() freopen("in.txt","w",stdout);
#define setlargestack(x) int _SIZE=x<<20;char *_PPP=(char*)malloc(_SIZE)+_SIZE;__asm__("movl %0, %%esp\n" :: "r"(_PPP));
#define read2(a,b) read(a),read(b)
#define read3(a,b,c) read(a),read(b),read(c)
#define readg(_x1,_y1,_x2,_y2) read(_x1),read(_y1),read(_x2),read(_y2)
#define USE_CIN_COUT ios::sync_with_stdio(0)
 
using namespace std;
 
int random(int l, int r) {
    static std::random_device rd;
    struct timeb timeSeed;
    ftime(&timeSeed);
    size_t seed = timeSeed.time * 1000 + timeSeed.millitm;  // milli time
    static std::mt19937 gen(seed);
    std::uniform_int_distribution<> u(l, r);
    return u(gen);
}
 
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int  ui;
typedef unsigned long long ull;
typedef pair<int, int> pii;
 
namespace fastIO{ 
    #define BUF_SIZE 100000 
    #define OUT_SIZE 100000 
    //fread->read 
    bool IOerror=0; 
    inline char nc(){ 
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; 
        if (p1==pend){ 
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); 
            if (pend==p1){IOerror=1;return -1;} 
            //{printf("IO error!\n");system("pause");for (;;);exit(0);} 
        } 
        return *p1++; 
    } 
    inline bool blank(char ch){return ch==32||ch==10||ch==13||ch==9;} 
    inline bool enter(char ch){return ch==10||ch==13;}
    inline void read(int &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (sign)x=-x; 
    } 
    inline void read(ll &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (sign)x=-x; 
    } 
    inline void read(double &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (ch==46){ 
            double tmp=1; ch=nc(); 
            for (;ch>=48&&ch<=57;ch=nc())tmp/=10.0,x+=tmp*(ch-48); 
        } 
        if (sign)x=-x; 
    } 
    inline void read(char *s){ 
        char ch=nc(); 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch; 
        *s=0; 
    } 
    inline void readln(char *s) {
        char ch=nc();
        for (;blank(ch);ch=nc());
        if(IOerror)return;
        for(;!enter(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
    }
    inline void read(char &c){ 
        for (c=nc();blank(c);c=nc()); 
        if (IOerror){c=-1;return;} 
    }
#undef OUT_SIZE 
#undef BUF_SIZE 
}
using fastIO::read;
 
int const N = 26;
 
bool w[N][N];
vector<int> G[N];
int E[N];
int n, m;
char f[1 << N];
 
inline void Remax(char& a, int b) {
    if (b > a)
        a = b;
}
 
int main() {
    USE_CIN_COUT;
    int T = 1;
    while (T--) {
        cin >> n >> m;
        for (int i = 0; i < m; ++i) {
            int x, y;
            cin >> x >> y;
            w[x][y] = w[y][x] = 1;
        }
        for (int i = 0; i < n; ++i) {
            int st = 1 << i;
            for (int j = 0; j < n; ++j)
                if (w[i][j]) {
                    st |= 1 << j;
                    G[i].push_back(j);
                }
            E[i] = st;
        }
        f[0] = 0;
        m = 1 << n;
        ll ans = 0;
        for (int i = 1; i < m; ++i) {
            int last = __builtin_ctz(i);
            f[i] = (int)f[i ^ (i & E[last])] + 1;
            Remax(f[i], (int)f[i ^ (1 << last)]);
            /*
            for (auto v : G[last])
                if ((1 << v) & i)
                    Remax(f[i], (int)f[i ^ (i & E[v])] + 1);
            */
            ans += (int)f[i];
        }
        cout << ans << '\n';
    }
    return 0;
}

F

比赛的时候一直T,遗憾-7,今早补题的时候觉得T的莫名其妙,结果把连边时候的判断从每次暴力/2的判断改成了位运算就过了(草
这里最大团点数等于补图的最大独立集,然后因为是二分图,所以最大独立集就是n-最大匹配数。
方案的话先把不在匹配里的全部加进去,然后类似于拓扑排序那样,如果删除了一个匹配中的点,那么匹配的另一边就必选,如果这样完成了之后还是有完整的匹配,全部选左点或者右点即可。

/* ***********************************************
Author        :BPM136
Created Time  :2019/8/1 15:32:22
File Name     :F.cpp
************************************************ */
 
#include <bits/stdc++.h>
#include <sys/timeb.h>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define USE_CIN_COUT ios::sync_with_stdio(0)
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define mkd(x) freopen(#x".in","w",stdout);
 
using namespace std;
 
int random(int l, int r) {
    static std::random_device rd;
    struct timeb timeSeed;
    ftime(&timeSeed);
    size_t seed = timeSeed.time * 1000 + timeSeed.millitm;  // milli time
    static std::mt19937 gen(seed);
    std::uniform_int_distribution<> u(l, r);
    return u(gen);
}
 
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;
typedef pair<int, int> pii;
 
int const N = 5005;
 
struct edge {
    int y, next;
}e[N * 70];
int last[N], ne;
 
void addedge(int x, int y) {
    e[++ne].y = y;
    e[ne].next = last[x];
    last[x] = ne;
}
 
int a[N];
 
bool chk(int x, int y) {
    int num = 0;
    while (x || y) {
        if (x % 2 != y % 2)
            ++num;
        x /= 2;
        y /= 2;
    }
    return num <= 1;
}
 
int col[N], dfn[N];
vector<int> lef, rig;
int n;
 
void dfs(int x, bool color) {
    col[x] = color;
    if (color) {
        rig.push_back(x);
        dfn[x] = SZ(rig);
    } else {
        lef.push_back(x);
        dfn[x] = SZ(lef);
    }
    for (int i = last[x]; i; i = e[i].next) {
        if (col[e[i].y] != -1) {
            //assert(col[e[i].y] != color);
            continue;
        }
        dfs(e[i].y, color ^ 1);
    }
}
 
bool vis[N];
int linker[N];
bool cha(int x) {
    for (int i = last[lef[x - 1]]; i; i = e[i].next) {
        int v = e[i].y;
        if (vis[dfn[v]] == 0) {
            vis[dfn[v]] = 1;
            if (linker[dfn[v]] == -1 || cha(linker[dfn[v]])) {
                linker[dfn[v]] = x;
                return 1;
            }
        }
    }
    return 0;
}
 
inline bool isbit2(int x) {
    if (x - (x & -x) == 0)
        return 1;
    return 0;
}
 
queue<int> Q;
bool vis2[N];
int tur[N];
 
int main() {
    USE_CIN_COUT;
    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    for (int i = 1; i <= n; ++i)
        for (int j = i + 1; j <= n; ++j)
            if (isbit2(a[i] ^ a[j])) {
                addedge(i, j);
                addedge(j, i);
            }
    memset(col, -1, sizeof(col));
    for (int i = 1; i <= n; ++i)
        if (col[i] == -1)
            dfs(i, 0);
    for (int i = 1; i <= SZ(rig); ++i)
        linker[i] = -1;
    int ans = 0;
    for (int i = 0; i < SZ(lef); ++i) {
        memset(vis, 0, sizeof(vis));
        if (cha(i + 1))
            ++ans;
    }
    cout << n - ans << '\n';
    memset(vis, 0, sizeof(vis));
    int tmp = 0;
    for (int i = 1; i <= SZ(rig); ++i) {
        if (linker[i] == -1)
            continue;
        vis[rig[i - 1]] = 1;
        vis[lef[linker[i] - 1]] = 1;
        tur[rig[i - 1]] = lef[linker[i] - 1];
        tur[lef[linker[i] - 1]] = rig[i - 1];
        ++tmp;
    }
    for (int i = 1; i <= n; ++i) {
        if (vis[i] == 1)
            continue;
        Q.push(i);
        vis2[i] = 1;
        ++tmp;
    }
    int cnt = 0, cnt1 = 0;
    while (Q.empty() == 0) {
        int now = Q.front();
        cout << a[now] << ' ';
        ++cnt;
        Q.pop();
        for (int i = last[now]; i; i = e[i].next) {
            if (vis2[e[i].y])
                continue;
            if (vis[e[i].y]) {
                vis2[e[i].y] = 1;
                vis2[tur[e[i].y]] = 1;
                Q.push(tur[e[i].y]);
                ++cnt1;
            }
        }
    }
    for (int i = 1; i <= SZ(rig); ++i) {
        if (linker[i] == -1)
            continue;
        if (vis2[lef[linker[i] - 1]] && vis2[rig[i - 1]])
            continue;
        ++cnt;
        ++cnt1;
        if (vis2[rig[i - 1]] == 0)
            cout << a[rig[i - 1]] << ' ';
        else
            cout << a[lef[linker[i] - 1]] << ' ';
    }
    cout << '\n';
    return 0;
}

G

其实写起来挺烦的,明明E那么好写大家都不去写,过分
这里 f i , j , k f_{i,j,k} fi,j,k到第i位,和第二个串的前j位都相同,而且第j+1位是k的串的数量
t t j , k tt_{j,k} ttj,k表示有多少个长度和第二个串相同的,而且前j位都相同,第j+1位是k的串的数量
预处理组合数转移就行

/* ***********************************************
Author        :BPM136
Created Time  :2019/8/1 14:13:52
File Name     :G.cpp
************************************************ */
 
#include <bits/stdc++.h>
#include <sys/timeb.h>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define USE_CIN_COUT ios::sync_with_stdio(0)
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define mkd(x) freopen(#x".in","w",stdout);
 
using namespace std;
 
int random(int l, int r) {
    static std::random_device rd;
    struct timeb timeSeed;
    ftime(&timeSeed);
    size_t seed = timeSeed.time * 1000 + timeSeed.millitm;  // milli time
    static std::mt19937 gen(seed);
    std::uniform_int_distribution<> u(l, r);
    return u(gen);
}
 
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;
typedef pair<int, int> pii;
 
int const N = 3005;
int const mod = 998244353;
 
inline void add(int& a, int b) {
    a += b;
    if (a >= mod)
        a -= mod;
}
 
char a[N], b[N];
int f[N][10], g[N][10], tt[N][10];
int C_sum[N];
int C[N][N];
int n, m;
 
int main() {
    USE_CIN_COUT;
    C[0][0] = C[1][0] = C[1][1] = 1;
    for (int i = 2; i < N; ++i) {
        C[i][0] = 1;
        for (int j = 1; j < N; j++)
            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
    }
    int T;
    cin >> T;
    while (T--) {
        cin >> n >> m;
        cin >> a >> b;
        memset(C_sum, 0, sizeof(C_sum));
        for (int i = m; i <= n; ++i)
            for (int j = m; j <= i; ++j)
                add(C_sum[i], C[i][j]);
        memset(f, 0, sizeof(f));
        memset(g, 0, sizeof(g));
        memset(tt, 0, sizeof(tt));
        g[0][0] = f[0][0] = 1;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                int k = j == 0 ? 0 : (b[j - 1] - '0');
                if (f[j][k] && n - i + j >= m) {
                    add(g[j + 1][a[i] - '0'], f[j][k]);
                    add(tt[j + 1][a[i] - '0'], (ll) f[j][k] * C[n - i - 1][m - j - 1] % mod);
                }
            }
            for (int j = 0; j <= m; ++j) {
                for (int k = 0; k < 10; ++k)
                    f[j][k] = g[j][k];
            }
        }
        int ans = 0;
        for (int i = 0; i < m; ++i) {
            int now = b[i] - '0';
            for (int j = 0; j <= 9; ++j)
                if (j > now)
                    add(ans, tt[i + 1][j]);
        }
        for (int i = 0; i < n; ++i)
            if (a[i] != '0' && n - i - 1 >= m)
                add(ans, C_sum[n - i - 1]);
        cout << ans << '\n';
    }
    return 0;
}

H

考虑构造一下,所有的aX,X表示其他字母,和所有的Xa,就能处理出每个a对应的位置。同理对于其他字母

/* ***********************************************
Author        :BPM136
Created Time  :2019/8/1 13:42:27
File Name     :H.cpp
************************************************ */
 
#include <bits/stdc++.h>
#include <sys/timeb.h>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define mkdfile() freopen("in.txt","w",stdout);
#define setlargestack(x) int _SIZE=x<<20;char *_PPP=(char*)malloc(_SIZE)+_SIZE;__asm__("movl %0, %%esp\n" :: "r"(_PPP));
#define read2(a,b) read(a),read(b)
#define read3(a,b,c) read(a),read(b),read(c)
#define readg(_x1,_y1,_x2,_y2) read(_x1),read(_y1),read(_x2),read(_y2)
#define USE_CIN_COUT ios::sync_with_stdio(0)
 
using namespace std;
 
int random(int l, int r) {
    static std::random_device rd;
    struct timeb timeSeed;
    ftime(&timeSeed);
    size_t seed = timeSeed.time * 1000 + timeSeed.millitm;  // milli time
    static std::mt19937 gen(seed);
    std::uniform_int_distribution<> u(l, r);
    return u(gen);
}
 
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int  ui;
typedef unsigned long long ull;
typedef pair<int, int> pii;
 
namespace fastIO{ 
    #define BUF_SIZE 100000 
    #define OUT_SIZE 100000 
    //fread->read 
    bool IOerror=0; 
    inline char nc(){ 
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; 
        if (p1==pend){ 
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); 
            if (pend==p1){IOerror=1;return -1;} 
            //{printf("IO error!\n");system("pause");for (;;);exit(0);} 
        } 
        return *p1++; 
    } 
    inline bool blank(char ch){return ch==32||ch==10||ch==13||ch==9;} 
    inline bool enter(char ch){return ch==10||ch==13;}
    inline void read(int &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (sign)x=-x; 
    } 
    inline void read(ll &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (sign)x=-x; 
    } 
    inline void read(double &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (ch==46){ 
            double tmp=1; ch=nc(); 
            for (;ch>=48&&ch<=57;ch=nc())tmp/=10.0,x+=tmp*(ch-48); 
        } 
        if (sign)x=-x; 
    } 
    inline void read(char *s){ 
        char ch=nc(); 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch; 
        *s=0; 
    } 
    inline void readln(char *s) {
        char ch=nc();
        for (;blank(ch);ch=nc());
        if(IOerror)return;
        for(;!enter(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
    }
    inline void read(char &c){ 
        for (c=nc();blank(c);c=nc()); 
        if (IOerror){c=-1;return;} 
    }
#undef OUT_SIZE 
#undef BUF_SIZE 
}
using fastIO::read;
 
const int maxn = 10010;
char s[15][15][maxn];
char ans[maxn];
int ok = 1;
int num[maxn];
 
int main() {
    memset(ans,0,sizeof(ans));
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 0;i < m*(m-1)/2;i++) {
        char t[3];
        int len;
        scanf("%s",t);
        scanf("%d",&len);
        int a = t[0]-'a';
        int b = t[1]-'a';
        getchar();
        gets(s[a][b]);
        for(int j = 0;j <= len;j++) s[b][a][j] = s[a][b][j];
    }
    for(int i = 0;i < m;i++) {
        int cnt = 0;
        memset(num,0,sizeof(num));
        for(int j = 0;j < m;j++) {
            if(i == j) continue;
            int len = strlen(s[i][j]);
            cnt = 0;
            for(int k = 0;k < len;k++) {
                if(s[i][j][k] == i+'a') cnt++;
                else num[cnt]++;
            }
        }
        int p = 0;
        for(int k = 0;k < cnt;k++) {
            if(p+num[k] >= n) {
                ok = 0;
                break;
            }
            if(ans[p+num[k]] != 0) ok = 0;
            ans[p+num[k]] = i+'a';
            p += (num[k]+1);
        }
        if(p+num[cnt] > n) ok = 0;
    }
    ans[n] = 0;
    if(ok == 0 || strlen(ans) != n) printf("-1\n");
    else {
        printf("%s\n",ans);
    }
    return 0;
}

I

注意一下输出的点的顺序有要求,比如第几个和第几个的距离为啥。

/* ***********************************************
Author        :BPM136
Created Time  :2019/8/1 12:23:59
File Name     :I.cpp
************************************************ */
 
#include <bits/stdc++.h>
#include <sys/timeb.h>
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define mkdfile() freopen("in.txt","w",stdout);
#define setlargestack(x) int _SIZE=x<<20;char *_PPP=(char*)malloc(_SIZE)+_SIZE;__asm__("movl %0, %%esp\n" :: "r"(_PPP));
#define read2(a,b) read(a),read(b)
#define read3(a,b,c) read(a),read(b),read(c)
#define readg(_x1,_y1,_x2,_y2) read(_x1),read(_y1),read(_x2),read(_y2)
#define USE_CIN_COUT ios::sync_with_stdio(0)
 
using namespace std;
 
int random(int l, int r) {
    static std::random_device rd;
    struct timeb timeSeed;
    ftime(&timeSeed);
    size_t seed = timeSeed.time * 1000 + timeSeed.millitm;  // milli time
    static std::mt19937 gen(seed);
    std::uniform_int_distribution<> u(l, r);
    return u(gen);
}
 
typedef long long ll;
typedef double db;
typedef long double ld;
typedef unsigned int  ui;
typedef unsigned long long ull;
typedef pair<int, int> pii;
 
namespace fastIO{ 
    #define BUF_SIZE 100000 
    #define OUT_SIZE 100000 
    //fread->read 
    bool IOerror=0; 
    inline char nc(){ 
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; 
        if (p1==pend){ 
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); 
            if (pend==p1){IOerror=1;return -1;} 
            //{printf("IO error!\n");system("pause");for (;;);exit(0);} 
        } 
        return *p1++; 
    } 
    inline bool blank(char ch){return ch==32||ch==10||ch==13||ch==9;} 
    inline bool enter(char ch){return ch==10||ch==13;}
    inline void read(int &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (sign)x=-x; 
    } 
    inline void read(ll &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (sign)x=-x; 
    } 
    inline void read(double &x){ 
        bool sign=0; char ch=nc(); x=0; 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        if (ch==45)sign=1,ch=nc(); 
        for (;ch>=48&&ch<=57;ch=nc())x=x*10+ch-48; 
        if (ch==46){ 
            double tmp=1; ch=nc(); 
            for (;ch>=48&&ch<=57;ch=nc())tmp/=10.0,x+=tmp*(ch-48); 
        } 
        if (sign)x=-x; 
    } 
    inline void read(char *s){ 
        char ch=nc(); 
        for (;blank(ch);ch=nc()); 
        if (IOerror)return; 
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch; 
        *s=0; 
    } 
    inline void readln(char *s) {
        char ch=nc();
        for (;blank(ch);ch=nc());
        if(IOerror)return;
        for(;!enter(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
    }
    inline void read(char &c){ 
        for (c=nc();blank(c);c=nc()); 
        if (IOerror){c=-1;return;} 
    }
#undef OUT_SIZE 
#undef BUF_SIZE 
}
using fastIO::read;
 
struct Point {
    double x,y;
    Point() {x = y = 0;}
    Point(double _x,double _y) : x(_x),y(_y) {}
};
 
const double PI = acos(-1.0);
 
void cp(Point p[],Point ans[]) {
    for(int i = 0;i < 3;i++) ans[i] = p[i];
}
 
const double eps = 1e-7;
int dcmp(double a,double b) {
    if(fabs(a-b) < eps) return 0;
    return a > b ? 1 : -1;
}
 
double w,h;
 
bool check(double a,double b,double c,Point p[]) {
    p[0] = Point(0,0);
    double alpha = acos((a*a+b*b-c*c)/(2*a*b));
    if(a <= h) {
        p[1] = Point(0,a);
        double sita = PI/2-alpha;
        p[2].x = b*cos(sita);
        p[2].y = b*sin(sita);
        if(dcmp(p[2].x,0) >= 0 && dcmp(p[2].x,w) <= 0 && dcmp(p[2].y,0) >= 0 && dcmp(p[2].y,h) <= 0) return true;
    }
    if(a <= w) {
        p[1] = Point(a,0);
        p[2].x = b*cos(alpha);
        p[2].y = b*sin(alpha);
        if(dcmp(p[2].x,0) >= 0 && dcmp(p[2].x,w) <= 0 && dcmp(p[2].y,0) >= 0 && dcmp(p[2].y,h) <= 0) return true;
    }
    if(a > h && dcmp(sqrt(a*a-h*h),w) <= 0) {
        p[1] = Point(sqrt(a*a-h*h),h);
        double sita = asin(h/a);
        double sita1 = sita-alpha;
        double sita2 = sita+alpha;
        p[2].x = b*cos(sita1);
        p[2].y = b*sin(sita1);
        if(dcmp(p[2].x,0) >= 0 && dcmp(p[2].x,w) <= 0 && dcmp(p[2].y,0) >= 0 && dcmp(p[2].y,h) <= 0) return true;
        p[2].x = b*cos(sita2);
        p[2].y = b*sin(sita2);
        if(dcmp(p[2].x,0) >= 0 && dcmp(p[2].x,w) <= 0 && dcmp(p[2].y,0) >= 0 && dcmp(p[2].y,h) <= 0) return true;
    }
    if(a > w && dcmp(sqrt(a*a-w*w),h) <= 0) {
        p[1] = Point(w,sqrt(a*a-w*w));
        double sita = acos(w/a);
        double sita1 = sita-alpha;
        double sita2 = sita+alpha;
        p[2].x = b*cos(sita1);
        p[2].y = b*sin(sita1);
        if(dcmp(p[2].x,0) >= 0 && dcmp(p[2].x,w) <= 0 && dcmp(p[2].y,0) >= 0 && dcmp(p[2].y,h) <= 0) return true;
        p[2].x = b*cos(sita2);
        p[2].y = b*sin(sita2);
        if(dcmp(p[2].x,0) >= 0 && dcmp(p[2].x,w) <= 0 && dcmp(p[2].y,0) >= 0 && dcmp(p[2].y,h) <= 0) return true;
    }
    return false;
}
 
double dis(Point a,Point b) {
    double dx = a.x-b.x;
    double dy = a.y-b.y;
    return sqrt(dx*dx+dy*dy);
}
 
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        double a,b,c;
        scanf("%lf%lf%lf%lf%lf",&w,&h,&a,&b,&c);
        Point p[3];
        Point ans[3];
        if(check(a,b,c,p)) cp(p,ans);
        if(check(a,c,b,p)) cp(p,ans);
        if(check(b,a,c,p)) cp(p,ans);
        if(check(b,c,a,p)) cp(p,ans);
        if(check(c,a,b,p)) cp(p,ans);
        if(check(c,b,a,p)) cp(p,ans);
        int flag = 0;
        for(int i = 0;i < 3;i++) {
            for(int j = 0;j < 3;j++) {
                for(int k = 0;k < 3;k++) {
                    if(flag) break;
                    if(i == j || j == k || i == k) continue;
                    if(dcmp(dis(ans[i],ans[j]),a) == 0 && dcmp(dis(ans[i],ans[k]),b) == 0 && dcmp(dis(ans[j],ans[k]),c) == 0) {
                        flag = 1;
                        printf("%.10f %.10f ",ans[i].x,ans[i].y);
                        printf("%.10f %.10f ",ans[j].x,ans[j].y);
                        printf("%.10f %.10f\n",ans[k].x,ans[k].y);
 
                    }
                }
            }
        }
    }
    return 0;
}

J

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值