Codeforces 524 结题报告

打的很快乐的一次比赛hiahiahia, 才A掉4题rating就涨了100+

距离比赛\(3\)天了, 由于博主实在太颓, 又补掉了\(E\)题, 到现在才发解题报告

A.

语法题, 读入输出就行了

#include<cstdio>
#include<algorithm>
#include<iostream>
#define rd read()
#define ll long long
using namespace std;

int read() {
    int X = 0, p = 1; char c = getchar();
    for (; c > '9' || c < '0'; c = getchar())
        if (c == '-') p = -1;
    for (; c <= '9' && c >= '0'; c = getchar())
        X = X * 10 + c - '0';
    return X * p;
}

int main()
{
    int n = rd, k = rd;
    ll a = 2 * n, b = 5 * n, c = 8 * n, ans = 0;
    ans = (a + k - 1) / k + (b + k - 1) / k + (c + k - 1) / k;
    cout << ans << endl;
 }

B.

把相邻两项放在一起, 多出的\(1\)项另外加上去

#include<cstdio>
#include<algorithm>
#define rd read()
using namespace std;

int read() {
    int X = 0, p = 1; char c = getchar();
    for (; c > '9' || c < '0'; c = getchar())
        if (c == '-') p = -1;
    for (; c <= '9' && c >= '0'; c = getchar())
        X = X * 10 + c - '0';
    return X * p;
}

int main()
{
    int n = rd;
    for (; n; --n) {
        int l = rd, r = rd, ans = 0;
        if ((r - l + 1) % 2 == 0) printf("%d\n", (l & 1 ? 1 : -1) * (r - l + 1) / 2);
        else {
            ans = (l & 1 ? 1 : -1) * (r - l) / 2;
            ans += (r & 1 ? -1 : 1) * r;
            printf("%d\n", ans);
        }
    }
 }

C.

简单的容斥

白色和黑色是交替出现的

一个\(w \times h\) 的矩阵, 如果 \(w \times h\) 为奇数, 则左下角的颜色会比另外一种颜色多出\(1\)个

接下来是计算方法, 算出的 黑色 或 白色 的个数表示 泼墨水之前的矩阵

泼白墨水时, 算出 \((x1, y1), (x2, y2)\) 这个矩阵内有多少个黑色方块, 并更新入答案

泼黑墨水时, 算出 \((x3, y3), (x4, y4)\) 这个矩阵内有多少个白色方块, 并更新入答案

这时我们发现两次泼墨水的范围会有交集, 这个相交的矩阵为 \((x5, y5), (x6, y6)\)

这个相交的矩阵内 第二次泼墨只记入了 白色方块的贡献, 而没有记入黑色方块的贡献(黑色方块在第一次泼墨时被染成了白色)

所以只需要把 这个矩阵内的 黑色方块的个数 加入黑色方块的总数即可

枚举横纵坐标就可以找到相交矩阵

下代码计算矩阵内某种颜色的方块数用一个函数可以解决, 我打麻烦了QAQ

#include<cstdio>
#include<algorithm>
#include<iostream>
#define rd read()
#define ll long long
using namespace std;
typedef pair<ll, ll> P;

ll n, m, numw, numb;
ll lsx[10], lsy[10], cntx, cnty;

const ll inf = 1e9 + 7;

ll read() {
    ll X = 0, p = 1; char c = getchar();
    for (; c > '9' || c < '0'; c = getchar())
        if (c == '-') p = -1;
    for (; c <= '9' && c >= '0'; c = getchar())
        X = X * 10 + c - '0';
    return X * p;
}

#define X first
#define Y second
void in(P &tmp) {
    tmp.X = rd; tmp.Y = rd;
    lsx[++cntx] = tmp.X;
    lsy[++cnty] = tmp.Y;
}

int jud(ll x, ll y, P tmp1, P tmp2, P tmp3, P tmp4) {
    if (x < tmp1.X || x > tmp2.X) return 0;
    if (x < tmp3.X || x > tmp4.X) return 0;
    if (y < tmp1.Y || y > tmp2.Y) return 0;
    if (y < tmp3.Y || y > tmp4.Y) return 0;
    return 1;
}

void up(P &a, P b) {
    if (a < b) a = b;
}

void down(P &a, P b) {
    if (a > b) a = b;
}

void cal() {
    P tmp1, tmp2, tmp3, tmp4;
    in(tmp1); in(tmp2); in(tmp3); in(tmp4);
    ll dx = tmp2.X - tmp1.X + 1, dy = tmp2.Y - tmp1.Y + 1;
    if ((dx * dy) % 2 && (tmp1.X + tmp1.Y) % 2) {
        numb -= dx * dy - dx * dy / 2;
        numw += dx * dy - dx * dy / 2;
    } else numb -= dx * dy / 2,
    numw += dx * dy / 2;
    dx = tmp4.X - tmp3.X + 1, dy = tmp4.Y - tmp3.Y + 1;
    if ((dx * dy) % 2 && (tmp3.X + tmp3.Y) % 2 == 0) {
        numw -= dx * dy - dx * dy / 2;
        numb += dx * dy - dx * dy / 2;
    } else numw -= dx * dy / 2,
    numb += dx * dy / 2;
    P tmp5 = P(inf, inf), tmp6 = P(0, 0);
    for (int i = 1; i <= 4; ++i)
        for (int j = 1; j <= 4; ++j) if (jud(lsx[i], lsy[j], tmp1, tmp2, tmp3, tmp4)) {
                down(tmp5, P(lsx[i], lsy[j])),
                up(tmp6, P(lsx[i], lsy[j]));
            }
    if (tmp6.X == 0) return;
    dx = tmp6.X - tmp5.X + 1, dy = tmp6.Y - tmp5.Y + 1;
    if ((dx * dy) % 2 && (tmp5.X + tmp5.Y) % 2) {
        numw -= dx * dy - dx * dy / 2;
        numb += dx * dy - dx * dy / 2;
    } else numw -= dx * dy / 2,
    numb += dx * dy / 2;
}
#undef x
#undef y

int main()
{
    int T = rd;
    for (; T; T--) {
        cntx = cnty = 0;
        n = rd; m = rd;// y <= n && x <= m (x, y)
        numb = n * m / 2;
        numw = n * m - numb;
        cal();
        cout << numw << " " << numb <<endl;
    }
}

D.

枚举+数列计算?

\(a_n=(4^n-1) \div 3\) 表示边长为 \(2^n\) 的矩阵分裂成 \(1 \times 1\) 的矩阵需要的操作数。 高中的数列知识应该算的很快

然后枚举 路径上的矩阵的边长为 \(2^{n-a} \ (a=1...n)\) , 至少要 \(2^a - 1\) 次操作才能造出存在这样的路径,

则左边界\(L=2^a-1\), 然后我们需要算出右边界\(R\),并判断\(k\) 是否在 \([L, R]\) 内。

把除掉这条路径上的 所有矩阵都分裂成 \(1 \times 1\) 的矩阵 就能算出 \(R\)

另外 \(R\) 的值会爆\(LL\), 所以我用了 \(long \ double\) QuQ

#include<cstdio>
#include<algorithm>
#include<iostream>
#define ll long long
#define rd read()
#define lb long double
using namespace std;

const ll inf = 1e9 + 7;

ll n, k;

ll read() {
    ll X = 0, p = 1; char c = getchar();
    for (; c > '9' || c < '0'; c = getchar())
        if (c == '-') p = -1;
    for (; c >= '0' && c <= '9'; c = getchar())
        X = X * 10 + c - '0';
    return X * p;
}

lb fpow(lb a, ll b) {
    lb res = 1;
    for (; b; b >>= 1, a = a * a)
        if (b & 1) res = res * a;
    return res;
}

int cal() {
    lb tmp1 = 0, tmp2 = 0, fac = 2;
    for (int i = 1; i <= n && i <= 50; ++i) {
        tmp1 += fac - 1;
        tmp2 += (2 * (fac - 1) - 1) * (fpow(4, n - i) - 1) / 3;
        if (tmp1 <= k && k <= tmp1 + tmp2) return n - i;
        if (tmp1 > k) return inf;
        fac *= 2;
    }
    return inf;
}

int main()
{
    int T = rd;
    for (; T; T--) {
        n = rd; k = rd;
        int res = cal();
        if (res == inf) puts("NO");
        else printf("YES %d\n", res);
    }
} 

E.

manacher算法

一个矩阵满足条件, 必须使

    1. 在每一行中, 出现次数为奇数的字符数 \(<=1\)
    2. 对应两行每种字符的个数相同

然后枚举列,把每一行看成一个字符, 进行manacher算出回文串的个数即可

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#define ll long long
using namespace std;
typedef bitset<28> BT;

const int N = 260;

int n, m, cnt[N * 2][N][27], len[N << 1], odd[N << 1];
BT num[N << 1][N];
char s[N][N];

int cmp(int L, int R, int x, int y) {
    if (odd[x] > 1 || odd[y] > 1) return 0;
    for (int k = 1; k <= 26; ++k)
        if (cnt[x][R][k] - cnt[x][L - 1][k] != cnt[y][R][k] - cnt[y][L - 1][k]) return 0;
    return 1;
}

int cal(int l, int r) {
    len[1] = 1; int pos = 1, R = 1;
    int res = 0;
    for (int i = 2; i <= 2 * n + 1; ++i) {
        if (i <= R) {
            if (len[2 * pos - i] < R - i + 1) len[i] = len[2 * pos - i];
            else {
                len[i] = R - i + 1;
                while (i + len[i] <= 2 * n + 1 && i - len[i] && cmp(l, r, i + len[i], i - len[i]))
                    R++, len[i]++, pos = i;
            }
        } else {
            len[i] = 1;
            while (i + len[i] <= 2 * n + 1 && i - len[i] && cmp(l, r, i + len[i], i - len[i]))
                R++, len[i]++, pos = i;
        }
        if (odd[i] <= 1) res += len[i] / 2;
    }
     // printf("%d\n", res);
    return res;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i)
        scanf("%s", s[i] + 1);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j) {
            for (int k = 1; k <= 26; ++k)
                cnt[i << 1][j][k] = cnt[i << 1][j - 1][k];
            cnt[i << 1][j][s[i][j] - 'a' + 1]++;
            BT tmp; tmp.set(s[i][j] - 'a' + 1);
            num[i << 1][j] = num[i << 1][j - 1] ^ tmp;
        }
    int ans = 0;
    for (int i = 1; i <= m; ++i)
        for (int j = 1; j <= i; ++j) {
            BT tmp;
            for (int k = 1; k <= n; ++k) {
                tmp = num[k << 1][j - 1] ^ num[k << 1][i];
                odd[k << 1] = tmp.count();
            }
            // printf("%d %d :", j, i);
            ans += cal(j, i);
        }
    printf("%d\n", ans);
}

原文地址:https://www.cnblogs.com/cychester/p/9879645.html

时间: 2024-11-10 02:07:31

Codeforces 524 结题报告的相关文章

初步了解--状态压缩dp---poj1185炮兵布阵结题报告

好吧,借助poj1185炮兵布阵这题,仔仔细细的了解了一下状态压缩动态规划 首先,借助题目,我们来看看状态压缩是个虾米东西..Ok follow me 一,所谓状态压缩 根据题意,我们得在长度为M 的地图上放置一些大炮(后面简称"放炮",应该不会被和谐吧),那么,首先不考虑山地,我们得把所有的放置方法都找出来,并且注意,这里只对于一行且长度为M(好吧,你可能要问考虑一行,左右互相隔2,互相不在攻击范围,那么上下呢?这里先不急,一步步来) 1,找出所有放炮的方法 假设长度为7,那么看下图

关于填报《国家自然科学基金资助项目结题报告》的补充说明

项目负责人在线提交<结题报告>后,只需打印系统生成的PDF版本,签字后交依托单位. 原<结题报告>撰写提纲与说明中第三项,要求随纸质结题报告提供的附件材料,在电子化后上传即可,无需再随结题报告报送纸质附件材料. <结题报告>中的摘要包括项目摘要和结题摘要两部分,其中项目摘要的内容从计划书中自动生成,结题摘要须以深入浅出的语言简明扼要地概括出项目的精华,如背景.方向.主要内容.重要结果.关键数据及其科学意义等.

poj1185炮兵布阵结题报告--初步了解--状态压缩dp

好吧,借助poj1185炮兵布阵这题,仔仔细细的了解了一下状态压缩动态规划 首先,借助题目,我们来看看状态压缩是个虾米东西..Ok follow me 一,所谓状态压缩 根据题意,我们得在长度为M 的地图上放置一些大炮(后面简称"放炮",应该不会被和谐吧),那么,首先不考虑山地,我们得把所有的放置方法都找出来,并且注意,这里只对于一行且长度为M(好吧,你可能要问考虑一行,左右互相隔2,互相不在攻击范围,那么上下呢?这里先不急,一步步来) 1,找出所有放炮的方法 假设长度为7,那么看下图

《基于Cortex-M4的ucOS-III的应用》课程设计 结题报告

<基于Cortex-M4的ucOS-III的应用>课程设计 结题报告 小组成员姓名:20155211 解雪莹 20155217 杨笛 20155227 辜彦霖 指导教师:娄嘉鹏 一.设计方案及可行性分析 题目要求:ucOS-III的移植:设计三个小实验:单一任务.多任务.并发任务. 1.设计方案 首先运行老师给的范例代码熟悉开发软件和开发板的使用:收集资料简单了解UCOSIII的基本概念,然后进行UCOSIII移植(移植到STM32f407开发板):移植成功后开始进行UCOSIII实例编程(实

20155211课程设计个人结题报告

20155211课程设计个人结题报告 个人贡献 参与课设题目讨论及完成全过程 辅助调试代码 资料收集 撰写小组结题报告 实践过程中的问题及解决: 编译之后出现如下错误:..\OBJ\HZ.axf: error: L6050U: The code size of this image (47788 bytes) exceeds the maximum allowed for this version of the linker. 出现错误的原因是:没有完全破解. 解决办法是:按照D:\实验箱资料2

有向图强连通分支的Tarjan算法讲解 + HDU 1269 连通图 Tarjan 结题报告

题目很简单就拿着这道题简单说说 有向图强连通分支的Tarjan算法 有向图强连通分支的Tarjan算法伪代码如下:void Tarjan(u) {dfn[u]=low[u]=++index//进行DFS,每发现一个新的点就对这个点打上时间戳,所以先找到的点时间戳越早,dfn[U]表示最早发现u的时间,low[u]表示u能到达的最早的时间戳.stack.push(u)//将U压入栈中for each (u, v) in E {if (v is not visted)//如果V点没有经历过DFS,则

浙江省第6届程序设计竞赛结题报告汇总 zoj3202-3212

zoj 3202 Second-price Auction 水题,不解释了,直接贴代码 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct node{ int x; int y; }; struct node number[105]; int cmp(struct node a,struct node b){

结题报告——2018级2016第二学期第三周作业9.24

题目一:[NOIP2002P]过河卒 描述 如图,A 点有一个过河卒,需要走到目标 B   点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点.例 如上图 C  点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C).卒不能通过对方马的控制点. 棋盘用坐标表示,A 点(0,0).B 点(n,m)(n,m 为不超过 20  的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C<>A,同

结题报告——2018级2016第二学期第五周作业9.24

F:[NOIP2008P]排座椅 描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来 之后,只有有限的D对同学上课时会交头接耳.同学们在教室中坐成了M行N列,坐在第i行第j列的同学的位置是(i,j),为了方便同学们进出,在教室中设 置了K条横向的通道,L条纵向的通道.于是,聪明的小雪想到了一个办法,或许可以减少上课时学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通 道的位置,因为如果一条