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("\n");
        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\n%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\n", tot);
    return 0;
}

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

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

原文地址:https://www.cnblogs.com/devilk-sjj/p/9086647.html

时间: 2024-11-05 22:34:03

2018/5/24模拟赛总结的相关文章

2019.10.24模拟赛赛后总结

本文原创,如果有不到位的地方欢迎通过右下角的按钮私信我! A.Icow Player 题目描述 被无止境的农活压榨得筋疲力尽后,Farmer John打算用他在MP3播放器市场新买的iCow来听些音乐,放松一下.FJ的iCow里存了N(1 <= N <= 1,000)首曲子,按1..N依次编号.至于曲子播放的顺序,则是按一个Farmer John自己设计的算法来决定: * 第i首曲子有一个初始权值R_i(1 <= R_i <= 10,000). * 当一首曲子播放完毕,接下来播放的

2018/02/26 模拟赛

第一题排序暴力 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<algorithm> 6 #include<cmath> 7 #include<utility> 8 #include<stdio.h> 9 #include<cstdlib> 10 #include<

11.24 模拟赛

T1 bzoj 4730 Alice和Bob又在玩游戏 题目大意: Alice和Bob在玩游戏 n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最小的点 Alice和Bob轮流操作,每回合选择一个没有被删除的节点x,将x及其所有祖先全部删除,不能操作的人输 思路: 根据博弈论的一些定理可以得到一个优秀的$n^2$做法 由$SG$定理得 每个点的$SG$函数值为$mex${子树内一个点的SG xor 该根节点其余儿子的SG} 因此对于每个点我们可以开一个t

2018/3/19 模拟赛 35分

T1 不会计算几何弃疗了. T2 写了个bitset结果还不如不优化(手动滑稽),因为测样例开小了空间忘了开回去所以0分. 正解是FFT,不会FFT.. T3 暴力35分,正解倍增floyd,学长还讲过但是还是错了,又多了一个要学的知识点. 原文地址:https://www.cnblogs.com/137shoebills/p/8602386.html

2018.7.3模拟赛

我真的是菜的一笔 T1: 一道贪心大水题,然后我wa了... 就是把它按照结束时间排个序,然后乱搞一下就行了 #include <cstdio> #include <cstdlib> #include <algorithm> int n,ans; struct Node{int t,s,k;} r[100005]; bool cmp(Node x,Node y){if(x.s!=y.s) return x.s<y.s;return x.k<y.k;} int

『8.24 模拟赛』ranwen的服务器

题目链接戳这里n(*≧▽≦*)n 题目描述 众所周知,ranwen建造出了强大的服务器网,规模十分庞大,有n个服务器,组成一个树形结构,1号点是总站,但是有时候可能会因为主机被回收,机房断电等事故造成服务器各种GG,现在有m个事件,可能为:1.查询x到根路径上第一个已经挂掉的服务器传输路径 2.x到y路径上的服务器传输路径全挂了.(不存在则输出0) 解题思路 上来先是树剖,然而只过了样例,爆0... 题面上提示了正解是并查集,但是并没有想出来,听完题解瞬间懂了.... 并查集,当然最方便的是合并

2018.11.1模拟赛总结

贪心 + 堆 因为可以不选满,所以可以把小于 \(0\) 的值赋值为 \(0\), 先考虑按 \(a_i\) 从大到小排序, 然后考虑选择 \([A + 1 \dots n]\) 中最大的 \(b_i\).但是这样不一定会成为最优解,我们从 \(A + 1\) 开始向 \(A + B\) 扫描,每一次尝试放弃前面的一个 \(a_i\) , 然后用当前的物品更新 \(a_i\) 的答案.前者可以通过用一个包含了第 \(A\) 个物品的 \(b_i - a_i\) 的 \(set\) 维护,后者可以

树的dfs序,p1539,其他经典问题,2018/11/08模拟赛T3

树的dfs序指从根节点进行dfs(先序遍历),每次到达某个点的时间和离开这个点的时间.它可以将树上的问题转换成序列问题进行处理. 比如对于p1539的样例可以这样解释. 每个点的左边数字表示进入该点的"时间",右边的数字表示离开该点的"时间".对dfs序的介绍就到这里. 然后来看一个例题: 先读入边,跑一遍dfs确定dfs序. 对于操作1,把点x的进入的"时间"+=a,把x出去的"时间"-=a 这样操作3询问根节点到y的路径点

2019.10.24模拟赛

T1 古代龙人的谜题 Mark Douglas 是一名调查员.他接受了「调查古代龙人」的任务.经过千辛万苦,Mark 终于找到了一位古代龙人.Mark 找到他时,他正在摆弄一些秘药,其中一些药丸由于是从很久以前流传下来的,发出了独特的光泽.古代龙人告诉了 Mark 一些他想知道的事情,看了看手中的秘药,决定考一考这位来访者. 古代龙人手中共有\(n\)粒秘药,我们可以用\(1\)表示「古老的秘药」,其余的用\(0\)表示.他将它们排成一列.古代龙人认为平衡是美的,于是他问 Mark 能选出多少个