2017.9.2 校内模拟赛

中规中矩的一套题。

然而辣鸡的我日常跪

卡SPFA是要哪样啊。。。再也不写SPFA了

100 + 0 + 70 = 170

“与”

(and.pas/.c/.cpp)

时间限制:1s;空间限制64MB

题目描述:

给你一个长度为n的序列A,请你求出一对Ai,Aj(1<=i<j<=n)使Ai“与”Aj最大。

Ps:“与”表示位运算and,在c++中表示为&。

输入描述:

第一行为n。接下来n行,一行一个数字表示Ai。

输出描述:

输出最大的Ai“与”Aj的结果。

样例输入:

3

8

10

2

样例输出:

8

样例解释:

8 and 10 = 8

8 and 2 = 0

10 and 2 = 2

数据范围:

20%的数据保证n<=5000

100%的数据保证 n<=3*10^5,0<=Ai<=10^9

乱写了一下,莫名其妙就过了。。。

对所有数二进制拆分,然后排个序

枚举二进制位

从大的开始找,若找到一组大的并且相等的数,就更新答案

每找完一位就丢掉一位

#include <cstdio>
#include <iostream>
#include <bitset>
#include <algorithm>

const int BUF = 12312323;
char Buf[BUF], *buf = Buf;

inline void read (int &now)
{
    for (now = 0; !isdigit (*buf); ++ buf);
    for (; isdigit (*buf); now = now * 10 + *buf - ‘0‘, ++ buf);
}

#define Max 300002
#define _L 31

struct Bit { int a; bool c[_L]; };
inline bool Comp (Bit A, Bit B) { return A.a > B.a; }
Bit key[Max];
int max (int a, int b) { return a > b ? a : b; }

int Main ()
{
    freopen ("and.in", "r", stdin);
    freopen ("and.out", "w", stdout);
    fread (buf, 1, BUF, stdin);
    int N, x; read (N); register int i, j, k;
    for (i = 1; i <= N; ++ i)
    {
        read (x), j = 31; key[i].a = x;
        for (; x; x >>= 1) key[i].c[-- j] = x % 2;
    }
    std :: sort (key + 1, key + 1 + N, Comp);
    long long Answer = 0;
    if (key[1].a == key[2].a)
        return printf ("%d", key[1].a), 0;
    int pos; static int mi[10]; mi[1] = 2;
    for (i = 2; i <= 31; ++ i)
        mi[i] = mi[i - 1] * 2;
    Answer = key[1].a & key[2].a;
    for (j = 0; j < _L; ++ j)
    {
        pos = 0;
        for (i = 1; i <= N; ++ i)
        {
            if (key[i].c[j] == 0 && i > pos) { pos = i; break; }
            if (key[i].a == key[i - 1].a)
                Answer = max (Answer, key[i].a);
        }
        for (i = 1; i < pos; i ++)
            key[i].a -= mi[_L - j];
    }
    printf ("%d", Answer);
    return 0;
}

int ZlycerQan = Main ();
int main (int argc, char *argv[]) {;}

小象涂色

(elephant.pas/.c/.cpp)

时间限制:1s,空间限制128MB

题目描述:

小象喜欢为箱子涂色。小象现在有c种颜色,编号为0~c-1;还有n个箱子,编号为1~n,最开始每个箱子的颜色为1。小象涂色时喜欢遵循灵感:它将箱子按编号排成一排,每次涂色时,它随机选择[L,R]这个区间里的一些箱子(不选看做选0个),为之涂上随机一种颜色。若一个颜色为a的箱子被涂上b色,那么这个箱子的颜色会变成(a*b)mod c。请问在k次涂色后,所有箱子颜色的编号和期望为多少?

输入描述:

第一行为T,表示有T组测试数据。

对于每组数据,第一行为三个整数n,c,k。

接下来k行,每行两个整数Li,Ri,表示第i个操作的L和R。

输出描述:

对于每组测试数据,输出所有箱子颜色编号和的期望值,结果保留9位小数。

样例输入:

3

3 2 2

2 2

1 3

1 3 1

1 1

5 2 2

3 4

2 4

样例输出:

2.062500000

1.000000000

3.875000000

数据范围:

40%的数据1 <= T <= 5,1 <= n, k <= 15,2 <= c <= 20

100%的数据满足1 <= T <= 10,1 <= n, k <= 50,2 <= c <= 100,1 <= Li <= Ri <= n

.

数学期望。。。看到就虚。。。。

暴力做法:dp是f[i][j][k]表示第i个箱子第j次染色,染为k颜色的概率

后发现对于每个箱子,它们的本质是相同的,也就是第几个箱子这一维状态是不需要存在的。所以dp状态可简化为f[i][j],表示操作i次,颜色变为j的概率。

读入时统计每个箱子操作的次数c[i],初始化f[0][1]=1;

F[i+1][j]+=f[i][j] * 0.5;

F[i+1][(j+k)%c]+=f[i][j] * 0.5 / c;

s[i]统计染色i次的颜色和期望值

然后加起来就好

#include <cstdio>
#include <iostream>
#include <cstring>

const int BUF = 12312312;
char Buf[BUF], *buf = Buf;
#define Max 55
inline void read (int &now)
{
    for (now = 0; !isdigit (*buf); ++ buf);
    for (; isdigit (*buf); now = now * 10 + *buf - ‘0‘, ++ buf);
}
typedef double flo;
int c[Max];
flo f[Max][Max << 1], s[Max], Answer;

int Main ()
{
    freopen ("elephant.in", "r", stdin);
    freopen ("elephant.out", "w", stdout);
    fread (buf, 1, BUF, stdin);
    int T; read (T); int N, C, K, x, y;
    for (register int i, j, k; T; -- T)
    {
        read (N), read (C), read (K);
        memset (f, 0, sizeof f); memset (s, 0, sizeof s);
        memset (c, 0, sizeof c); Answer = 0; f[0][1] = 1;
        for (i = 1; i <= K; ++ i)
        {
            read (x), read (y);
            for (j = x; j <= y; ++ j) ++ c[j];
        }
        for (i = 0; i <= K; ++ i)
            for (j = 0; j < C; ++ j)
            {
                f[i + 1][j] += f[i][j] * 0.5;
                for (k = 0; k < C; ++ k)
                    f[i + 1][j * k % C] += f[i][j] * 0.5 / C;
            }
        for (i = 0; i <= K; ++ i)
            for (j = 0; j < C; ++ j)
                s[i] += f[i][j] * j;
        for (i = 1; i <= N; ++ i) Answer += s[c[i]];
        printf ("%.9lf\n", Answer);
    }
    return 0;
}
int ZlycerQan = Main ();
int main (int argc, char *argv[]) {;}

行动!行动!

(move.pas/.c/.cpp)

时间限制:1s;空间限制:128MB

题目描述:

大CX国的大兵Jack接到一项任务:敌方占领了n座城市(编号0~n-1),有些城市之间有双向道路相连。Jack需要空降在一个城市S,并徒步沿那些道路移动到T城市。虽然Jack每从一个城市到另一个城市都会受伤流血,但大CX国毕竟有着“过硬”的军事实力,它不仅已经算出Jack在每条道路上会损失的血量,还给Jack提供了k个“简易急救包”,一个包可以让Jack在一条路上的流血量为0。Jack想知道自己最少会流多少血,不过他毕竟是无脑的大兵,需要你的帮助。

输入描述:

第一行有三个整数n,m,k,分别表示城市数,道路数和急救包个数。

第二行有两个整数,S,T。分别表示Jack空降到的城市编号和最终要到的城市。

接下来有m行,每行三个整数a,b,c,表示城市a与城市b之间有一条双向道路。

输出描述:

Jack最少要流的血量。

样例输入:

5 6 1

0 3

3 4 5

0 1 5

0 2 100

1 2 5

2 4 5

2 4 3

样例输出:

8

数据范围:

对于30%的数据,2<=n<=50,1<=m<=300,k=0;

对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;

对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

堆优化的Dijkstra,用Spfa会被卡

F[i][j] 表示第i个点用了j个包的血量

转移时分用和不用两种情况讨论即可

#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>

const int BUF = 12312313;
char Buf[BUF], *buf = Buf;
#define INF (1 << 30)
inline void read (int &now)
{
    for (now = 0; !isdigit (*buf); ++ buf);
    for (; isdigit (*buf); now = now * 10 + *buf - ‘0‘, ++ buf);
}

#define P_Q std :: priority_queue <D>
inline int min (int a, int b) { return a < b ? a : b; }

struct D
{
    int id, c, d; D () {}
    D (int _x, int _y, int _z) : id (_x), c (_y), d (_z) {}
    bool operator < (const D now) const
    {
        return this->d > now.d;
    }
};

#define Max 10009
struct E { int v, d; E *n; };
E poor[Max * 50], *list[Max], *Ta = poor;
P_Q Heap;
bool visit[Max][12];
int f[Max][12];

int Main ()
{
    freopen ("move.in", "r", stdin);
    freopen ("move.out", "w", stdout);
    fread (buf, 1, BUF, stdin);
    int N, M, K, S, T; read (N), read (M), read (K);
    register int i, j; int x, y, z; read (S), read (T);
    for (i = 1; i <= M; ++ i)
    {
        read (x), read (y), read (z);
        ++ Ta, Ta->v = y, Ta->d = z, Ta->n = list[x], list[x] = Ta;
        ++ Ta, Ta->v = x, Ta->d = z, Ta->n = list[y], list[y] = Ta;
    }
    Heap.push (D (S, 0, 0)); D res; int V, C, now;
    memset (f, 0x3f, sizeof f); E *e; int Answer = INF;
    for (f[S][0] = 0; !Heap.empty (); Heap.pop ())
    {
        res = Heap.top (); now = res.id, C = res.c;
        if (visit[now][C]) continue;
        visit[now][C] = true;
        for (e = list[now]; e; e = e->n)
        {
            V = e->v;
            if (f[V][C] > f[now][C] + e->d)
            {
                f[V][C] = f[now][C] + e->d;
                Heap.push (D (V, C, f[V][C]));
            }
            if (C < K && f[V][C + 1] > f[now][C])
            {

                f[V][C + 1] = f[now][C];
                Heap.push (D (V, C + 1, f[V][C + 1]));
            }
        }
    }
    for (i = 0; i <= K; ++ i) Answer = min (Answer, f[T][i]);
    printf ("%d", Answer);
    return 0;
}
int ZlycerQan = Main ();
int main (int argc, char *argv[]) { ; }
时间: 2024-10-10 10:34:53

2017.9.2 校内模拟赛的相关文章

2017.6.11 校内模拟赛

题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛 T1 自己在纸上模拟一下后就会发现 可以用栈来搞一搞事情 受了上次zsq 讲的双栈排序的启发.. 具体就是将原盘子大小copy一下排个序 用两个指针维护两个数组(原数据 和 排序后的数据), 即分为1数据和2数组 将小于1指针指向的数据的2数组中的数据全部压入栈中 后进行消除, 将栈栈顶元素与当前1数组中的1指针指向的元素进行比较 相同则消除 后重复过程 直至指针超过N 后判断一下是否两个指针都超过了N... #incl

校内模拟赛 Zbq&#39;s Music Challenge

Zbq's Music Challenge 题意: 一个长度为n的序列,每个位置可能是1或者0,1的概率是$p_i$.对于一个序列$S$,它的得分是 $$BasicScore=A\times \sum_{i=1}^{n}{S_i} \tag{1}$$ $$ combo(i)=\left\{ \begin{aligned} &S_i & &i=1 \\ &combo(i-1)+1 & &i\neq 1 ~\mathrm{and}~ S_i=1 \\ &

2017 9 11 noip模拟赛T2

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=205; int map[N][N]; int d[N],tag[N],book[N],f[N]; int n,m; void work(int x) { memset(d,63,sizeof(d)); memset(book,0,sizeof(book)); memset(f,0,sizeof(

[20180816]校内模拟赛

T1 清理(clear) 问题描述 小 C 最近自己开发了一款云盘软件,目前已有??个用户.小C 的云盘上的文件会被后台分成两种类型,活动 文件和非活动文件,活动文件即可能常用的文件,会被放在高速服务器上给用户提供高速下载服务.用户 上传一个文件时,这个文件会被设置为活动文件.由于高速服务器内存大小有限,小 C 需要把一些文件 设为非活动文件,有以下两种设置方式:1.把上传时间前??早的文件全部设为非活动文件:2.把第??个用户上 传的文件全部设为非活动文件.注意这两种方式操作的对象都是所有文件

校内模拟赛T1大美江湖

这就是一个模拟题,注意1234分别对应左右上下横坐标和纵坐标的判断就好了 题解: 需要注意的是,向上取整ceil函数是对于一个double值返回一个double值,也就是说在ceil里面的类型一定要是double,否则会炸 代码: #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #include<cstring> #include<string>

校内模拟赛:确定小组

  [问题描述] 有n个人坐成一排,这n个人都在某一个小组中,同一个小组的所有人所坐的位置一定是连续的. 有一个记者在现场进行采访,他每次采访都会询问一个人其所在的小组有多少人,被询问的每个人都给出了正确的答案,但是由于时间仓促,记者不一定询问了每个人,我们记录一个长度为n的答案序列,序列的第i个数表示第i个人的回答,如果为0则表示记者没有询问过这个人. 记者发现,对于一些情况,他可以唯一确定这排所有人的分组,而对于另外一些情况则不能,于是记者开始好奇,对于某一个答案序列,他能不能做到这一点,如

校内模拟赛20170604

香蕉锤--双向链表 #include<iostream> #include<cstdio> using namespace std; inline int read(){ int num=0,t=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} ret

5.13 校内模拟赛

... 果然是dalao们做难题做多了后 简单题水不起来了吗.. 5.13解题报告 300分 T1写了差不多30~40分钟 T2写了不到5min (当时怀疑有坑..) T3推了大概1个多小时的式子, 然后又加上调试差不多一个半小时 时间分配就这样..感觉T2出的太过简单了..直接是个模板 T1 并查集 + 乱搞 T2 快速幂模板 T3 Dp T1 : codevs 2796 最小完全图 二次联通门 : codevs 2796 最小完全图 /* codevs 2796 最小完全图 并查集 + 乱搞

2017 9 15 noip模拟赛

t1: #include<cstdio> #include<cstring> const int N=1000010; int a[N],b[N]; int sum=1,maxx=0; int main() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); int n; scanf("%d"