• 2018/5/24模拟赛总结


    shzr带病AK虐爆全场...

    T1n皇后:

    这题没啥好说的...

    T2有重复元素的排列问题:

    【问题描述】
    设R={ r1, r2 , …, rn}是要进行排列的n个元素。其中元素r1, r2 , …, rn可能相同。试设计一个算法,列出R的所有不同排列。
    【编程任务】
    给定n 以及待排列的n 个元素。计算出这n 个元素的所有不同排列。
    【输入格式】
    由perm.in输入数据。文件的第1 行是元素个数n,1≤n≤500。接下来的1 行是待排列的n个元素。
    【输出格式】
    计算出的n个元素的所有不同排列输出到文件perm.out中。文件最后1行中的数是排列总数。

    出锅出在T2上,T掉了7个点...

    考试时的想法是:生成r[1]~r[n]的全排列,之后用Hash+map去重(比只用map要快一(很)些(多))

    然而还是T掉了..仔细一看数据范围(n≤500),全排列(n!)的复杂度能给到三十分就已经是仁慈了...

    正解应该是用一个桶,记录每个字母的个数,然后枚举26个字母的全排列就好了..

    正解代码如下:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,f[501],a[501],ans;
    char r[501];
    void search(int t) {
        int k;
        if(t>n) {
            ans++;
            for(k=1;k<=n;k++) printf("%c",a[k]+96);
            printf("
    ");
            return;
        }
        for(k=1;k<=26;k++)
            if(f[k]>0) {
                a[t]=k; f[k]--;
                search(t+1);
                f[k]++;
            }
    }
    int main() {
        scanf("%d",&n);
        cin>>r;
        for(int i=0;i<n;i++) f[r[i]-96]++;
        search(1);
        printf("%d",ans);
        return 0;
    }
    

    但wzx同学发现了一种神奇做法:stl里的next_permutation

    实测开(O_2) 8ms,不过正解200多ms是smg..,stl大法好!

    代码如下:

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define re register
    using namespace std;
    
    int n, tot;
    char ch[500 + 1];
    
    int main() {
        scanf("%d
    %s", &n, ch);
        sort(ch, ch + n);
        do {
            puts(ch);
            ++tot;
        }while(next_permutation(ch, ch + n));
        printf("%d", tot);
        return 0;
    }
    

    T3装载问题:

    【问题描述】
    有一批共n个集装箱要装上艘载重量为c的轮船,其中集装箱i的重量为wi。找出一种最优装载方案,将轮船尽可能装满,即在装载体积不受限制的情况下,将尽可能重的集装箱装上轮船。
    【输入格式】
    由文件load.in给出输入数据。第一行有2个正整数n和c。n是集装箱数,c是轮船的载重量。接下来的1行中有n个正整数,表示集装箱的重量。
    【输出格式】
    将计算出的最大装载重量输出到文件load.out。
    【输入样例】
    5 10
    7 2 6 5 4
    【输出样例】
    10

    一看,这明显是01背包啊!loli太毒瘤了..明明说是只考搜索的模拟赛,用搜索的这道题都T掉了...

    可以把货物的重量看做价值(因为要求重量最大嘛..),然后跑一个sb背包就好.

    闲得无聊打了一个暴力,被极限数据卡成狗...

    T4字符序列(characts)

    【问题描述】
    从三个元素的集合[A,B,C]中选取元素生成一个N个字符组成的序列,使得没有两个相邻字的子序列(子序列长度=2)相同。例:N = 5时ABCBA是合格的,而序列ABCBC与ABABC是不合格的,因为其中子序列BC,AB是相同的。
    对于由键盘输入的N(1<=N<=12),求出满足条件的N个字符的所有序列和其总数。

    一开始以为长度不定,两个区间的位置没有限制,check函数写了一个三重循环的(把四重优化了一下)

    然后发现不对啊!搜索里面这么check不超时才鬼了嘞

    开始仔细读题:

    • 子序列长度=2

    • 两个相邻字的子序列

    一下子check的复杂度就变成O(n)了...

    打了打搜索发现(n=12)的数据好像要1s多才能跑出来..

    算了,不剪枝了,打一个12的表就好了

    loli出题的时候好像没有考虑到可打表的问题.

    我的打表程序比正解还短233,毕竟只有12的大小..

    T5图的m着色问题color

    【问题描述】
    给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的。图的m着色问题是对于给定图G和m种颜色,找出所有不同的着色法。
    【编程任务】
    对于给定的无向连通图G和m种不同的颜色,编程计算图的所有不同的着色法。
    【输入格式】
    文件color.in输入数据。第1行有3个正整数n,k 和m,表示给定的图G有n个顶点和k条边,m种颜色。顶点编号为1,2,…,n。接下来的k行中,每行有2个正整数u,v,表示图G 的一条边(u,v)。
    【输出格式】
    程序运行结束时,将计算出的不同的着色方案数输出到文件color.out中。

    当时用邻接表(又是一道图论题,毒瘤啊)没有打出来..就用的邻接矩阵,生成颜色的全排列再(n^2)遍历一遍判断

    T了三个点(三个点卡卡时就过了..满地打滚求O3优化...)

    考完以后用邻接表打了一遍,代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define re register
    using namespace std;
    
    const int MAXN = 100 + 5;
    const int MAXM = MAXN * (MAXN - 1) / 2;
    
    int n, k, m;
    int tot, c[MAXN];
    bool vis[MAXN];
    
    int edge_num, head[MAXN];
    struct Edge {
    	int to, nxt;
    }h[MAXM << 1];
    
    inline int read() {
        int x=0; char ch = getchar();
        while(ch<'0' || ch>'9') ch = getchar();
        while(ch>='0' && ch<='9')
          x=(x<<3)+(x<<1)+ch-48, ch=getchar();
        return x;
    }
    
    inline void Add(int from, int to) {
    	h[++edge_num].nxt = head[from];
    	h[edge_num].to = to;
    	head[from] = edge_num;
    }
    
    void dfs(int u) {
        if(u == n) {
            ++tot;
            return;
        }
        for(re int i=1; i<=m; ++i) {
        	bool fl = 1;
        	for(re int j=head[u+1]; j; j=h[j].nxt)
        		if(c[h[j].to] == i) {
        			fl = 0;
        			break;
    			}
    		if(!fl) continue;
    		c[u + 1] = i;
    		dfs(u + 1);
    		c[u + 1] = 0;
    	}
    }
    
    int main() {
        n = read(), k = read(), m = read();
        for(re int i=1; i<=k; ++i) {
            int x = read(), y = read();
            Add(x, y), Add(y, x);
        }
        dfs(0);
        printf("%d
    ", tot);
        return 0;
    }
    

    这次模拟赛其实好多人都能AK的,但只有一个人AK...

    大家都交卷交的太早了...

  • 相关阅读:
    单点登陆
    【springmvc学习】常用注解总结
    Excel里函数中的万金油,你确定不要点进来看看?
    Maven3在Eclipse上安装插件
    VSCode 云同步扩展设置 Settings Sync 插件
    Ubuntu 18.04 root 使用ssh密钥远程登陆
    [Asp.net] C# 操作Excel的几种方式 优缺点比较
    开源框架Autofac使用入门
    C# .net Ueditor实现图片上传到阿里云OSS 对象存储
    [python]TypeError: string indices must be integers解决方法
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9086647.html
Copyright © 2020-2023  润新知