T1 字符串

小X十分热爱学习。有一天,他刚学完“漂亮的k字符串”的概念:给定长度为n的字符串和整数k,k能整除n,如果该字符串满足以下两个条件:

  1. s是一个回文串,即对于任意1≤i≤n,Si=Sn+1-i(其中Si表示字符串中第i个字母)
  1. s以k为周期,即对于任意1≤i≤n-k, Si=Sk+i(其中Si表示字符串中第i个字母)

就称该字符串为“漂亮的k字符串“。

比如说“abaaba“就是一个漂亮的3字符串,而”abccba“则不是。

小Y是小X 的同学,她对“漂亮的K字符串”也很感兴趣,她有一些字符串,每个字符串都是由小写字母构成,并且对于每个字符串她都会给出一个k,想让小X帮自己把该字符串修改成“漂亮的k字符串”。小Y可以选择任意位置的字母并将他们改成任意其他小写字母。由于小Y的字符串又长又多,小X又想在小Y前表现自己,在1s内把每个字符串修改为“漂亮的k字符串”,于是就请你来帮忙求出每个字符串最少需要修改多少字符才能成为“漂亮的k字符串”。

分析该字符串的性质,我们可以发现要满足上述性质的字符串必须满足两点:

  • 对于任意 \([n(k - 1) + 1, ~ nk + 1]\) 的子串 \(S\),必须满足 \(S_{i} = S_{k - i + 1}\)。

  • 对于所有的串 \(S_i(1 \le i \le \frac{n}{k})\),第 \(t\) 个字符满足 \(S_{i,t} = S_{j,t}(i \ne j)\)。

综上,我们可以得出上述的字符可以划分为若干个不相交的集合,对于每个集合中的元素,我们考虑求出所有字符变为同一个字符需要的最少次数,累加即可。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, k, sum;
int cnt[26];
char s[N]; void solve()
{
cin >> n >> k;
cin >> s + 1;
int ans = 0;
for (int i = 1; i <= (k + 1) >> 1; i ++ )
{
int sum = 0, res = 1e9;
for (int j = 0; j < 26; j ++ ) cnt[j] = 0;
for (int j = i; j <= n; j += k) cnt[s[j] - 'a'] ++ , sum ++ ;
if (i != k / 2 + 1) for (int j = k - i + 1; j <= n; j += k) cnt[s[j] - 'a'] ++ , sum ++ ;
for (int j = 0; j < 26; j ++ ) res = min(sum - cnt[j], res);
ans += res;
}
cout << ans << endl;
} int main()
{
int T;
cin >> T;
while (T -- ) solve();
return 0;
}

T2 抓

小X这天兴致勃勃的要跑去小Y家玩。在他向小Y家行走了t秒后,小Y这时得知小X要来他家玩,认为上周小X弄丢自己作业后没有道歉是非常不对的,于是怒火中烧,要抓住小X让他给自己道歉。小X也突然意识到上周自己刚把小Y的作业弄丢,于是放弃去往小Y家,开始逃跑。

小X和小Y居住的城市有n个小区,这些小区由n-1条双向道路连接起来,每两个小区之间都可以通过这n-1条道路中的某几条到达,并且每条道路的长度只有1m。小X住在1号小区,小Y住在n号小区。小X的跑步速度为1m/s(在小Y开始抓小X时,小X既可以选择跑向和当前小区有道路的小区,也可以选择原地不动),而小Y的跑步速度为2m/s。并且小Y对整个城市和小X都十分了解,每时每刻都在以最短的路径跑向小X。小X想要让小Y尽可能晚的抓到自己,因为时间越长小Y越不愤怒,这样他就能获得小Y的原谅了。你能帮小X计算出从小Y出发抓小X最长经过几秒后抓住小X吗?

第一行包括两个整数n(3≤n≤105),t(1≤t≤n-1),分别表示小区个数和最开始经过了t秒后小Y出发抓小X。

接下来n-1行每行包含两个整数x(1≤x≤n),y(1≤y≤n)表示第x和第y个小区之间有一条长度为1m的双向道路。

对于100%的数据, 3≤n≤10^5, 1≤t≤n-1且t小于1号小区到n号小区的距离。

我们需要先求出 \(t\) 秒后小X的位置,才能够进行下一步判断,考虑从 \(1\) 和 \(n\) 分别跑一次最短路,记小Y为起点的最短路为 \(dist1\),小X为起点的最短路为 \(dist2\),那么经过 \(t\) 秒后的节点 \(u\) 一定满足 \(dist1[i] + t = dist1[1]\) 且 \(dist2[i] - t = 0\),因为 \(u\) 在 \(1 \to n\) 的路径上,所以两者需要都满足才可以。

我们求出 \(u\) 后,考虑重新求 \(u\) 为起点的最短路,替换原来的 \(dist2\),考虑小X能达到的地方必定满足 \(dist1[i] \ge dist2[i] \times 2\),否则小Y可以比小X先到达目的地,小X在途中就会被抓,对于合法的目的地,求出小Y到目的地的时间的最大值即可。

参考代码

#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
int n, t, ans;
int h[N], e[N << 1], ne[N << 1], idx;
int st[N], dist1[N], dist2[N]; void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
} void dijkstra(int S, int dist[])
{
memset(st, 0, sizeof st);
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0, S}), dist[S] = 0;
while (heap.size())
{
auto t = heap.top();
heap.pop();
int u = t.second, distance = t.first;
if (st[u]) continue;
st[u] = true;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (dist[j] > distance + 1)
{
dist[j] = distance + 1;
heap.push({dist[j], j});
}
}
}
} int main()
{
cin >> n >> t;
memset(h, -1, sizeof h);
memset(dist1, 0x3f, sizeof dist1);
memset(dist2, 0x3f, sizeof dist2);
for (int i = 1; i < n; i ++ )
{
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
dijkstra(n, dist1), dijkstra(1, dist2);
int now = 0;
for (int i = 1; i <= n; i ++ )
if (dist1[i] + t == dist1[1] && dist2[i] - t == 0)
now = i;
memset(dist2, 0x3f, sizeof dist2);
dijkstra(now, dist2);
for (int i = 1; i <= n; i ++ )
if (dist1[i] >> 1 >= dist2[i])
ans = max(ans, (dist1[i] + 1) >> 1);
cout << ans;
return 0;
}

T3 彩虹

多年以后,小X和小Y结婚了,他们搬到了一个新的城市。该城市有r条南北方向的街道,也有r条东西方向的街道。每一条南北街道中的都与每一条东西街道交叉;第x条南北街道和第y条东西街道之间的十字路口用(x,y)表示。为了从十字路口(x,y)移动到十字路口(x’,y’),小需要|x - x‘|+|y - y’|分钟。

小X知道这座城市有n条美丽的彩虹会在十字路口出现。他想带领小Y尽可能多地观看这些彩虹。对于每一个i=1,…,n,小X知道第i条彩虹将第ti分钟开始时在十字路口(x,y)出现并在很短的时间内消失。小X和小Y必须在第ti分钟开始时就出现(x,y)处才会看到彩虹,并且小X和小Y对于每条彩虹只观看一瞬间即可。

目前小X和小Y在第0分钟开始时在他们的新家,位于十字路口(1,1)。作为小X的好兄弟,小X希望你能帮他求出他最多可以带小Y参观多少条彩虹?

在任意时刻最多只有一条彩虹。

第一行两个整数r(1≤r≤500),和n(1≤n≤100000),表示南北街道和东西街道的条数、彩虹出现的个数。

接下来n行数据,每行包括三个整数ti(1≤ti≤1000000),xi(1≤xi≤r),yi(1≤yi≤r),表示第ti分钟有一条彩虹出现在十字路口(xi,yi)处。

考虑先对 \(t_i\) 排序,设 \(dp[i]\) 表示到 \(t_i\) 时间节点时最多能看见多少彩虹。

设 \(t_0 = 0\),对于任何可达的 \(i\),如果 \(j ~ (0 \le j < i)\) 可以转移到 \(i\),必有 \(dp[i] = \max\limits_{j = 0}^{i - 1} dp[j] + 1\)。

不妨将 \(dp\) 初始化为 \(-1\),对每个 \(j\) 判断是否可达,转移的必要条件是 \(\mid x_i - x_j \mid + \mid y_i - y_j \mid \le t_i - t_j\),如果可达且可以转移则 \(dp[i] = \max(dp[i], dp[j] + 1)\)。

但是这样是 \(O(n^2)\) 的,我们需要进一步优化,对于状态 \(i\),我们事实上只用考虑最近的 \(2r\) 个状态,因为 \(2r\) 个状态内必然可以跑到所有地点,因此再往前找状态是不优的,因此时间复杂度 \(O(rn)\)。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int r, n, dp[N];
struct Node
{
int t, x, y;
}q[N]; bool cmp(Node a, Node b)
{
return a.t < b.t;
} int calc(Node a, Node b)
{
return abs(a.x - b.x) + abs(a.y - b.y);
} int main()
{
cin >> r >> n;
for (int i = 1; i <= n; i ++ ) cin >> q[i].t >> q[i].x >> q[i].y;
sort(q + 1, q + n + 1, cmp);
memset(dp, -1, sizeof dp);
q[0] = {0, 1, 1}, dp[0] = 0;
for (int i = 1; i <= n; i ++ )
for (int j = max(0, i - 2 * r); j < i; j ++ )
if (calc(q[i], q[j]) <= q[i].t - q[j].t && dp[j] != -1)
dp[i] = max(dp[i], dp[j] + 1);
int ans = 0;
for (int i = 1; i <= n; i ++ ) ans = max(ans, dp[i]);
cout << ans;
return 0;
}

T4 游戏

更多年之后,小X和小Y垂垂老矣,只能窝在家里玩游戏了。

有一个由非负整数组成的长度为n的数组a。小X和小Y轮流行动,每个人最初的得分都等于0。小X先行动。

让我们来描述一下游戏中的一个行动:

在一个行动中,玩家选择数组中的任何一个元素并将其从数组中移除,并使用玩家当前的分数对其进行异或。

即如果玩家当前的分数是x,而选择的元素是y,那么他的新分数将是x⊕y。这里⊕表示按位异或运算。

被移除的元素后在以后的行动中不能被选取。

当数组为空时游戏结束。

游戏结束时,赢家是得分最高的选手。如果两位选手得分相同,那就是平局。

从前面几道题我们就可以看出来,小X和小Y都是非常聪明的人,都会以最优的方式让自己获得最大的得分。请你来判定一下,谁会赢下比赛或者比赛平局。

第一行一个整数t(1≤t≤1000)表示数据的组数。

接下来有t组数据,每组数据的第一行包括一个整数n(1≤n≤100000),表示数组元素个数。第二行包含n个整数a1、a2……an,表示数组中的每个元素。且(0≤ai≤1000000000)

对于每组数据,输出一个字符串。如果小X赢下比赛,输出“WIN”(不含双引号)

如果小Y赢下比赛,输出“LOSE”(不含双引号),如果平局,输出“DRAW”。每组数据的输出独占一行。

首先考虑平局的情况,当且仅当所有数异或为 \(0\) 时才会平局,否则一定有胜负,所有的数都会被异或到两人手中,最后小X与小Y两人手中的数异或和为 \(0\) 就说明相等,不为零一定分胜负。

接下来考虑异或和的最高位,这个最高位的出现次数一定是奇数,如果这个位被人取走,那么他就是胜者。我们考虑什么情况下这个位会被人取走:

  • 总的数字个数为偶数时,先手优先取走这个 \(1\),无论后手取什么,先手必定可以对称的使这个 \(1\) 存在,先手必胜。

  • 总的数字个数为奇数时,考虑这个 \(1\) 的个数 \(cnt\),如果 \(cnt \equiv 1 \pmod 4\),那么先手取走这个 \(1\),然后后手取或不取先手只需要对称的做法即可,先手必胜。

  • 总的数字个数为奇数时,如果 \(cnt \equiv 3 \pmod 4\),无论先手取不取走这个 \(1\),后手对称的做同样操作,最后一个 \(1\) 一定会被先手取走,此时后手最高位为 \(1\),先手为 \(0\),因此后手必胜。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, a[N]; int lowbit(int x)
{
return x & -x;
} void solve()
{
int sum = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]), sum ^= a[i];
if (!sum) return puts("DRAW"), void();
if (!(n & 1)) return puts("WIN"), void();
while (sum > lowbit(sum)) sum -= lowbit(sum);
int cnt = 0;
for (int i = 1; i <= n; i ++ )
if (sum & a[i]) cnt ++ ;
if (cnt % 4 == 1) puts("WIN");
else puts("LOSE");
} int main()
{
int T;
scanf("%d", &T);
while (T -- ) solve();
return 0;
}

NZOJ 模拟赛7的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  3. NOIP第7场模拟赛题解

    NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...

  4. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  5. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  6. 小奇模拟赛9.13 by hzwer

    2015年9月13日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿(explo) [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞 ...

  7. PKUSC 模拟赛 day1 下午总结

    下午到了机房之后又困又饿,还要被强行摁着看英文题,简直差评 第一题是NOIP模拟赛的原题,随便模拟就好啦 本人模拟功力太渣不小心打错了个变量,居然调了40多分钟QAQ #include<cstd ...

  8. [GRYZ]寒假模拟赛

    写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...

  9. BZOJ2741: 【FOTILE模拟赛】L

    2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1170  Solved: 303[Submit][Status] ...

  10. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

随机推荐

  1. 【YashanDB知识库】update/delete未选中行时,v$transaction视图没有事务,alter超时问题

    问题现象 1.alter table修改表字段名,卡住,超时. 2.查看v$transaction事务视图,没有看到事务记录. 3.问题单:调整表结构时超时 问题风险及影响 无风险 问题影响版本 客户 ...

  2. ES7学习笔记(二)ES的集群原理

    发现 发现是节点之间彼此发现,形成集群的一个过程.这个过程发生的场景有很多,比如:你启动了一个集群节点,或者一个节点确认主节点已经挂掉了,或者一个新的主节点被选举了. 咱们在配置集群的时候在配置文件中 ...

  3. 消息队列的对比测试与RocketMQ使用扩展

    消息队列的对比测试与RocketMQ使用扩展     本文的主要内容包括以下几个方面: 原有的消息技术选型 RocketMQ与kafka 测试对比 如何构建自己的消息队列服务 RocketMQ扩展改造 ...

  4. C++ 性能反向优化——用哈希表unordered_map消除if else导致性能降低。

    从代码整洁的角度考虑,对于不同的值将调用相同参数的不同函数,我们通常可以通过建立从值到对应函数指针的哈希表,从而将if else消除.但实际可能使性能更低,以下是测试例子. 原因在于,if else分 ...

  5. Coze插件发布!PDF转Markdown功能便捷集成,打造你的专属智能体

    近日,TextIn开发的PDF转Markdown插件正式上架Coze平台. 在扣子搜索"pdf转markdown",或在Coze平台搜索"pdf2markdown&quo ...

  6. Angular 18+ 高级教程 – Reactive Forms

    前言 上一篇的 Ajax 和这一篇的表单 (Form) 都是前端最最最常见的需求. 为此,Angular 分别提供了两个小型库来帮助开发者实现这些需求: Ajax – HttpClient Form ...

  7. Azure – 对比 AWS Research Report

    前言 最近有机会接触了一下 AWS, 在对比完之后决定继续用 Azure, 这里小小记入一下. VM & SQL Server Azure 和 AWS 都可以选择 2 in 1, 或者 Web ...

  8. ASP.NET Core – Razor Pages 冷知识

    Multiple Form Binding 问题 在一个 page 里面有 2 张 form, 那么就会有 2 个 model binding. 当任何一个 submit 的时候. 由于 2 个 mo ...

  9. 柳婼 の PAT甲级题解

      1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 102 ...

  10. 十五,Spring Boot 整合连接数据库(详细配置)

    十五,Spring Boot 整合连接数据库(详细配置) @ 目录 十五,Spring Boot 整合连接数据库(详细配置) 最后: JDBC + HikariDataSource(Spring Bo ...