SDNU_ACM_ICPC_2021_Winter_Practice_1st [个人赛]

K - Color the ball

题意:

有n个气球,每次都给定两个整数a,b,给a到b内所有的气球涂一个颜色,问你第m个气球有几个颜色,m属于[1,n],气球开始没有颜色

思路:

很简单的前缀和

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <cstring>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
inline int IntRead()
{
char ch = getchar();
int s = 0, w = 1;
while(ch < '0' || ch > '9')
{
if(ch == '-') w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
s = s * 10 + ch - '0',
ch = getchar();
}
return s * w;
}
int tr[100005], sum[100005], a, b;
int main()
{ int n;
while(cin>>n && n)
{
for(int i = 1; i <= n; i++)
tr[i] = 0;
for(int i = 1; i <= n; i++)
{
cin>>a>>b;
tr[a]++;
tr[b + 1]--;
}
for(int i = 1; i <= n; i++)
{
sum[i] = sum[i - 1] + tr[i];
}
cout<<sum[1];
for(int i = 2; i <=n; i++)
cout<<' '<<sum[i];
cout<<endl;
}
return 0;
}

H - 最大子矩阵

题意:

给你n乘以 m的整数矩阵,在上面找一个 x乘以 y的子矩阵,使得子矩阵中元素的和最大

思路:

直接利用二维前缀和,然后再通过循环扫一遍不断跟新最大值,即可。我当时wa了三遍,为什么呢?噢!是我把输入m,n,x,y写在了最外面,而不是在循环里面,fuck!但是也就是因为这个不经意的小错误让我对这个题又有了别样的想法,这个子矩阵不一定要按着是x行y列来的,可以是y行x列,都是矩阵,没有什么不同的,举个栗子:

3 5 1 3

1 2 3 4 5

1 2 3 4 5

1 2 3 4 5

如果只按照1行3的矩阵来搜,那最大值只是3+4+5=12;然而这个矩阵中最大的子矩阵是5 + 5 + 5 = 15;这就很坑 了,但是很显然出题人没有注意到这点,但是我还是写了的,保险点

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <cstring>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
ll tr[1050][1050], sum[1050][1050];
int n, a, b, c, d;
inline int IntRead()
{
char ch = getchar();
int s = 0, w = 1;
while(ch < '0' || ch > '9')
{
if(ch == '-')
w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
s = s * 10 + ch - '0',
ch = getchar();
}
return s * w;
}
int main()
{ n = IntRead();
while(n--)
{
a = IntRead();//就是这些输入一不小心放在了循环的外面,导致我wa了三次,淦
b = IntRead();
c = IntRead();
d = IntRead();
for(int i = 1; i <= a; i++)
{
for(int j = 1; j <= b; j++)
cin>>tr[i][j];
}
for(int i = 1; i <= a; i++)
{
for(int j = 1; j <= b; j++)
{
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + tr[i][j];//求的是二维前缀和
}
}
ll maxn = 0;//该maxn是x行y列的最大值
for(int i = c; i <= a; i++)
{
for(int j = d; j <= b; j++)
{
maxn = max(maxn, sum[i][j] + sum[i - c][j - d] - sum[i - c][j] - sum[i][j - d]);//不断更新最大值
}
}
ll maxn2 = 0;//该maxn2是y行x列的子矩阵的最大值
for(int i = d; i <= a; i++)
{
for(int j = c; j <= b; j++)
{
maxn2 = max(maxn2, sum[i][j] + sum[i - d][j - c] - sum[i - d][j] - sum[i][j - c]);
}
}
cout<<max(maxn2, maxn)<<endl;//输出最大的那个
}
return 0;
}

F - Andy's First Dictionary

题意:

不断输入一堆字符串,有大写有小写也有非字母,让你将其中的英文单词全部转换成小写并按字典序输出

思路:

因为是不断输入,单词之间用的是空格隔开,所以可以用cin不断输入,不用考虑空格,然后对输入的字符串进行遍历,看这个字符是不是字母,如果是字母就把他变小写,如果不是就把他变空格,后期用stringstream可以消除空格。然后再把改造好的字符串塞进set中去自动重排序

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
string s, temp;
set<string>tr;
stringstream ss;
int main()
{
while(cin>>s)
{
for(int i = 0; i < s.size(); i++)
{
if(isalpha(s[i]))
s[i] = tolower(s[i]);
else
s[i] = ' ';
}
ss.clear();
ss<<s;
while(ss>>temp)
tr.insert(temp);
}
set<string>::iterator it;
for(it = tr.begin(); it != tr.end(); it++)
cout<<*it<<endl;
return 0;
}

A - XORwice

题意:

给你两个数a, b,让你找到一个数x使得a ^ x + b ^ x的值最小,输出这个最小值

思路:

1.找规律,直接输出a^b(我也不懂原理.jpg

#include<bits/stdc++.h>
using namespace std;
int a, b, n;
int main()
{
cin>>n;
while(n--)
{
cin>>a>>b;
int c = a^b;
cout<<c<<endl;
}
return 0;
}

2.jkgg那里嫖来的很巧妙的位运算的方法

先进行分析,如果a,b的二进制数的同一位都是1,那么x的那一位就是1,这样能保证x^a x^b的值都是0,加起来就是0 ,如果a, b 的二进制数的同一位都是0,那x的那一位就是0,这样也是保证x^a x ^ b的和为0, 如果a b 的同一位不同,则无论x的那一位是多少,x ^ a 与 x ^ b 的和都为1

那么我们如何知道a,b的二进制数的同一位是多少呢?利用&1求和来讨论即可,同为1时,&1得到的是2,而同为0的时候得到的全为0 一个是1一个是0 的时候得到的是1,但是因为如果一个是1一个是0,则x的这一位是多少就没有意义,所以可以简化一下,如下

#include <bits/stdc++.h>
using namespace std;
int t;
int a, b;
int ta, tb;
int temp;
int xx[35];
int ans;
int main()
{
scanf("%d", &t);
while(t--)
{
int x = 0;
memset(xx, 0, sizeof(xx));
scanf("%d %d", &a, &b);
ta = a;//保存一下a和b
tb = b;
for(int i = 1; i <= 32; ++i)
{
temp = (1 & a) + (1 & b);
if(temp == 2) xx[i] = 1;
else xx[i] = 0;//简化在此
a >>= 1;//右移一位,继续进行判断
b >>= 1;
}
for(int i = 32; i >= 1; --i)//这个地方很巧妙,是从后往前遍历的,当xx[i]还是0的时候,无论怎么左移值都不变,左移就可以相当于二进制最后多了一个0,可以继续进行加xx[i]的操作,实现二进制数的构造
{
x <<= 1;
x += xx[i];
}
cout << x << endl;
ans = (ta ^ x) + (tb ^ x);
}
return 0;
}

X 其实等于(a | b)-(a & b)

/*还有一个函数,能实现十进制转任意进制的的转换,而且是直接转换成字符数组,方便对每一位进行操作*/
itoa(a, c, 16)
/*a就是十进制数字,c是用来接收的字符数组,最后一个参数是几进制
可以用该函数进行二进制的操作
*/

M - The Factor

题意:

给你一堆数,让你求这些所有数的乘积的一个至少有三个因子的因子,也就是找到这n个数的乘积的一个最小的不是素数的因子

思路:

因为数据范围很小,直接暴力求每个数的因子放进数组,(如果最后一个因子不是1,记得也要放进数组),然后用sort排序,然后用tr[0] * tr[1],即得到答案

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <set>
using namespace std;
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
inline int IntRead()
{
char ch = getchar();
int s = 0, w = 1;
while(ch < '0' || ch > '9')
{
if(ch == '-')
w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
s = s * 10 + ch - '0',
ch = getchar();
}
return s * w;
}
ll n, m, a, b, tr[100005], len;
int main()
{
n = IntRead();
while(n--)//n个样例
{
len = 0;
m = IntRead();//m个数
for(int i = 0; i < m; i++)//循环求每个数的所有因子
{
a = IntRead();
for(int j = 2; j * j <= a; j++)//暴力求a的因子
{
while(a % j == 0)
{
a /= j;
tr[len++] = j;
}
}
if(a > 1)//当a最后除不尽,是素数的时候,不要忘了放进数组
tr[len++] = a;
}
sort(tr, tr +len);
if(len < 2)
cout<<-1<<endl;
else
cout<<1ll * tr[0] * tr[1]<<endl;
}
return 0;
}

G - Covered Points Count

题意:

给你n对数(a,b),表示区间[a, b]的每个点都被覆盖了一次,要求输出从重叠1次到重叠n次的点的个数,并用空格隔开

思路:

第一想法肯定是用差分前缀和,通过扫一遍数组即可,但是奈何数据太狗,开不了1e18的数组,所以就只有用离散化来求解

还不是太明白为什么是这么做,先献上代码吧,等以后想明白了再回来解释

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <set>
using namespace std;
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
map<ll, ll>mp;
ll tr[200005];
ll n;
int main()
{
cin>>n;
for(int i = 0; i < n; i++)
{
ll a, b;
cin>>a>>b;
mp[a]++;
mp[b + 1]--;
}
ll l = 0, cnt = 0;
map<ll,ll>::iterator it;
for(it = mp.begin(); it != mp.end(); it++)
{
tr[cnt] += (it -> first - l);
l = it -> first;
cnt += it -> second;
// cout<<tr[cnt]<<' '<<l<<' '<<cnt<<endl;
}
for(int i = 1; i <= n; i++)
cout<<tr[i]<<' ';
cout<<'\n';
return 0;
}

C - Palindromifier

题意:

输入一个字符串,让你通过最多三十次的操作,使该字符串变成长度不超过1e6 的回文串,操作1:让第二个到第x个字符倒序添加到原字符串的左边,简称L,操作2:让第x个字符到第n-1个字符倒序添加到字符串的右边,简称R

思路:

一看就很复杂对吧,其实这个题代码不过短短几行!

首先看题目中的一句话:

It is guaranteed that under these constraints there always is a solution. Also note you do not have to minimize neither the number of operations applied, nor the length of the resulting string, but they have to fit into the constraints.

翻译过来就是:在这些约数下,总有一个解决方案,你不必最小化应用操作数量和结果字符串的长度,但是他们必须符合条件

(其实就是说,如果有多种情况,只需写出一种情况即可,这就很友好了,因为如果他本来是回文串,你也可以通过操作让她变成其他回文串,也就是说你可以找一个规律,让所有字符串都适合)

然后就可以先求一下字符串的长度n = s.size();

第一步:R n - 1,

这步就是把倒数第二位的字母单独挑出来放在最后

第二步:L n

这步就是把原来字符串的第2位到第n位(n是一直不变的,因为操作是将第2位到第m-1位倒序,这里的m是指总的字符串的长度,而我第一步已经将倒数第二个字符复制到最后面去,所以说,原来的倒数第一已经不是倒数第一,是倒数第二也就是可以复制了,所以是2 到 n,这里的n是原来字符串的长度,可能有点绕口,慢慢琢磨琢磨就能懂)

第三步:L 2

这步就是把最后一位的字母弄到第一位来,这样才能保证是回文串,但是又不能直接将最后一位弄过来,但是我们经过第一步第二步的转换,也就是最后一位是倒数第三位,而倒数第三位经过第二步的操作,变成了第二位,所以我们要把第二位弄到开头就行,正正好符合L的操作,所以是L 2

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
string s;
cin>>s;
int n = s.size();
cout<<3<<endl;
cout<<"R"<<' '<<n - 1<<endl;
cout<<"L"<<' '<<n<<endl;
cout<<"L"<<' '<<2<<endl;
return 0;
}

SDNU_ACM_ICPC_2021_Winter_Practice_1st [个人赛] 2021.1.19 星期二的更多相关文章

  1. 日常Javaweb 2021/11/19

    Javaweb Dao层: //连接数据库,实现增查功能 package dao; import java.sql.Connection; import java.sql.DriverManager; ...

  2. 2021.12.19 eleveni的刷题记录

    2021.12.19 eleveni的刷题记录 0. 本次记录有意思的题 0.1 每个点恰好经过一次并且求最小时间 P2469 [SDOI2010]星际竞速 https://www.luogu.com ...

  3. 2021.07.19 P2294 狡猾的商人(差分约束)

    2021.07.19 P2294 狡猾的商人(差分约束) [P2294 HNOI2005]狡猾的商人 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.差分约束最长路与最短 ...

  4. 2021.07.19 P2624 明明的烦恼(prufer序列,为什么杨辉三角我没搞出来?)

    2021.07.19 P2624 明明的烦恼(prufer序列,为什么杨辉三角我没搞出来?) [P2624 HNOI2008]明明的烦恼 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn ...

  5. 2021.07.19 BZOJ2654 tree(生成树)

    2021.07.19 BZOJ2654 tree(生成树) tree - 黑暗爆炸 2654 - Virtual Judge (vjudge.net) 重点: 1.生成树的本质 2.二分 题意: 有一 ...

  6. Noip模拟44 2021.8.19

    比较惊人的排行榜 更不用说爆零的人数了,为什么联赛会这么难!!害怕了 还要再努力鸭 T1 Emotional Flutter 考场上没切掉的神仙题 考率如何贪心,我们把黑色的条延长$s$,白色的缩短$ ...

  7. Noip模拟20 2021.7.19

    T1 玩具 题目读错意思直接报零... 拼接方式没读懂以为是个数学题,用卡特兰数,可是的确想多了 数据范围表达出你怎么暴力都行,选择$n^3,dp$ 相当于一片森林,每次多加一条边就合并成一棵树 在$ ...

  8. 2021.8.19考试总结[NOIP模拟44]

    T1 emotional flutter 把脚长合到黑条中. 每个黑条可以映射到统一区间,实际操作就是左右端点取模.长度大于$k$时显然不合法. 然后检查一遍区间内有没有不被黑条覆盖的点即可. 区间端 ...

  9. 日常Java 2021/10/19

    Java集合框架 Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射. Collection接口又有3种子类型,Li ...

随机推荐

  1. windows 下命令行关闭进程。

    使用 进程名关闭 taskkill /im mspaint.exe /f 使用 进程id 关闭 taskkill /im 12555 /f

  2. burpsuite进阶使用

    .Burpsuite:爆破 个人建议选择pro破解版的,免费版的太鸡肋,爆破不能设置线程,速度超乎你想像 浏览器和burpsuite设置代理后,开启抓包,截获数据包后,右键选择发送到repeater修 ...

  3. 自适应查询执行:在运行时提升Spark SQL执行性能

    前言 Catalyst是Spark SQL核心优化器,早期主要基于规则的优化器RBO,后期又引入基于代价进行优化的CBO.但是在这些版本中,Spark SQL执行计划一旦确定就不会改变.由于缺乏或者不 ...

  4. 华为Mate20 Adb驱动失败

    今天拿到同事一台华为Mate20,准备装个包,结果发现adb一直 no devices,AndroidStudio当然也显示 no connected devices 开发者模式也打开了,USB调试也 ...

  5. Github标星26k+!一个神奇的软件!1分钟即可打造了一个科幻风格的终端

    Github掘金计划项目分类汇总(原创不易,若有帮助,欢迎分享/点赞): 编程基础 :精选编程基础如学习路线.编程语言相关的开源项目. 计算机基础:精选计算机基础(操作系统.计算机网络.算法.数据结构 ...

  6. 利用基于Go Lang的Hugo配合nginx来打造属于自己的纯静态博客系统

    Go lang无疑是目前的当红炸子鸡,极大地提高了后端编程的效率,同时有着极高的性能.借助Go语言我们 可以用同步的方式写出高并发的服务端软件,同时,Go语言也是云原生第一语言,Docker,Kube ...

  7. Java日常开发的21个坑,你踩过几个?

    前言 最近看了极客时间的<Java业务开发常见错误100例>,再结合平时踩的一些代码坑,写写总结,希望对大家有帮助,感谢阅读~ 1. 六类典型空指针问题 包装类型的空指针问题 级联调用的空 ...

  8. easyui中加载table列表数据 第一次有数据第二次没有数据问题

    $('#allUsingProductTable').datagrid({  加载数据时,第二加载时table会发生变化会出现找不到问题.如果是弹框没有影响,弹框出现出现列表每次都会执行销毁方法. 解 ...

  9. C# ——获取各国时间

    DateTime dt = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now, TimeZoneInfo.Local); DateTime dt1 = TimeZo ...

  10. 入门Kubernetes -基础概念

    一.Kubernetes概述 Kubernetes ,又称为 k8s(首字母为 k.首字母与尾字母之间有 8 个字符.尾字母为 s,所以简称 k8s)或者简称为 "kube" ,是 ...