zoukankan      html  css  js  c++  java
  • 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...

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

  • 相关阅读:
    day01--计算机硬件基础笔记
    22 Jun 18 Django,ORM
    21 Jun 18 Django,ORM
    20 Jun 18 复习, mysql
    20 Jun 18 Django,ORM
    19 Jun 18 复习, 正则表达式
    19 Jun 18 Django
    15 Jun 18 复习, shutil模块
    15 Jun 18 Django
    14 Jun 18 复习, form表单
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9086647.html
Copyright © 2011-2022 走看看