B.真的是签到题
题意:
输
出
三
遍
N
U
C
2020
!
!
!
输出三遍NUC2020!!!
输出三遍NUC2020!!!
题解:
确
实
是
真
!
签
到
题
,
p
u
t
s
输
出
确实是真!签到题,puts输出
确实是真!签到题,puts输出
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int main()
{
//ios::sync_with_stdio(false);
//cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
puts("NUC2020!!!");
puts("NUC2020!!!");
puts("NUC2020!!!");
return 0;
}
A.俄罗斯方块
题意:
10
∗
10
的
图
10*10的图
10∗10的图
给
四
种
俄
罗
斯
的
图
形
,
按
俄
罗
斯
的
游
戏
规
则
,
下
降
遇
到
即
停
给四种俄罗斯的图形,按俄罗斯的游戏规则,下降遇到即停
给四种俄罗斯的图形,按俄罗斯的游戏规则,下降遇到即停
但
是
如
果
遇
到
整
行
满
的
情
况
不
消
除
但是如果遇到整行满的情况不消除
但是如果遇到整行满的情况不消除
给
出
n
次
下
降
的
图
形
和
最
左
块
的
坐
标
给出n次下降的图形和最左块的坐标
给出n次下降的图形和最左块的坐标
题解:
n
<
=
10
并
且
图
还
很
小
n<=10并且图还很小
n<=10并且图还很小
直
接
模
拟
下
降
过
程
即
可
直接模拟下降过程即可
直接模拟下降过程即可
对
每
个
方
块
的
下
落
,
判
断
每
个
点
下
个
位
置
是
否
会
碰
到
东
西
对每个方块的下落,判断每个点下个位置是否会碰到东西
对每个方块的下落,判断每个点下个位置是否会碰到东西
如
果
没
有
碰
到
就
继
续
下
落
,
碰
到
了
就
停
止
,
把
图
绘
上
去
即
可
如果没有碰到就继续下落,碰到了就停止,把图绘上去即可
如果没有碰到就继续下落,碰到了就停止,把图绘上去即可
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int a[20][20];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
cin>>n;
for(int i=1,x,y;i<=n;i++){
cin>>y>>x;
if(y==1){
int z=1;
while(!a[z+1][x]&&!a[z+1][x+1]&&z<10)z++;
a[z][x]=a[z-1][x]=a[z][x+1]=a[z-1][x+1]=1;
}
else if(y==2){
int z=1;
while(!a[z+1][x]&&!a[z+1][x+1]&&!a[z+1][x+2]&&z<10)z++;
a[z][x]=a[z][x+1]=a[z][x+2]=a[z-1][x]=1;
}
else if(y==3){
int z=1;
while(!a[z+1][x]&&!a[z+1][x+1]&&!a[z+1][x+2]&&!a[z+1][x+3]&&z<10)z++;
a[z][x]=a[z][x+1]=a[z][x+2]=a[z][x+3]=1;
}
else{
int z=1;
while(!a[z+1][x]&&!a[z+1][x+1]&&!a[z+1][x+2]&&z<10)z++;
a[z][x]=a[z][x+1]=a[z][x+2]=a[z-1][x+1]=1;
}
}
for(int i=1;i<=10;i++,cout<<endl)
for(int j=1;j<=10;j++)
cout<<a[i][j]<<' ';
return 0;
}
K.签个到
题意:
给
n
个
数
,
进
行
m
次
操
作
给n个数,进行m次操作
给n个数,进行m次操作
每
次
操
作
可
以
使
得
任
意
一
个
数
加
或
减
他
的
下
标
每次操作可以使得任意一个数加或减他的下标
每次操作可以使得任意一个数加或减他的下标
问
m
次
操
作
后
这
个
数
列
的
极
差
最
大
是
多
少
问m次操作后这个数列的极差最大是多少
问m次操作后这个数列的极差最大是多少
题解:
想
让
极
差
最
大
肯
定
是
只
修
改
一
个
数
,
把
他
修
改
成
最
大
或
最
小
想让极差最大肯定是只修改一个数,把他修改成最大或最小
想让极差最大肯定是只修改一个数,把他修改成最大或最小
记
录
一
下
数
列
的
最
大
值
最
小
值
记录一下数列的最大值最小值
记录一下数列的最大值最小值
对
于
每
一
个
数
,
找
他
和
最
小
值
或
最
大
值
的
最
大
差
对于每一个数,找他和最小值或最大值的最大差
对于每一个数,找他和最小值或最大值的最大差
通
过
对
该
位
的
值
加
减
下
标
可
以
扩
大
这
个
差
值
通过对该位的值加减下标可以扩大这个差值
通过对该位的值加减下标可以扩大这个差值
看
修
改
哪
一
个
能
使
得
极
差
最
大
看修改哪一个能使得极差最大
看修改哪一个能使得极差最大
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
ll a[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ll n,m;cin>>n>>m;
ll mi=inf,mx=-inf;
for(int i=1;i<=n;i++)cin>>a[i],mi=min(mi,a[i]),mx=max(mx,a[i]);
if(n==1){cout<<0;return 0;}
ll ans=0;
for(int i=1;i<=n;i++){
ll k=max(abs(a[i]-mi),abs(a[i]-mx));
ans=max(ans,k+i*m);
}
cout<<ans;
return 0;
}
E.简单的线性代数
题意:
给
一
个
矩
阵
A
和
整
数
k
,
已
知
A
k
=
0
给一个矩阵A和整数k,已知A^k=0
给一个矩阵A和整数k,已知Ak=0
求
E
+
A
1
+
…
…
+
A
k
−
1
的
逆
求E+A^1+……+A^k-1的逆
求E+A1+……+Ak−1的逆
题解:
矩
阵
和
整
数
其
实
是
可
以
类
比
的
矩阵和整数其实是可以类比的
矩阵和整数其实是可以类比的
所
以
完
全
可
以
类
比
成
等
比
数
列
所以完全可以类比成等比数列
所以完全可以类比成等比数列
然
后
用
一
下
等
比
数
列
的
求
和
公
式
然后用一下等比数列的求和公式
然后用一下等比数列的求和公式
即
E
−
A
k
E
−
A
即\frac{E-A^k}{E-A} \quad
即E−AE−Ak
然
后
题
目
要
求
的
是
这
个
式
子
的
逆
然后题目要求的是这个式子的逆
然后题目要求的是这个式子的逆
A
∗
B
=
E
,
其
中
B
是
A
的
逆
A*B=E,其中B是A的逆
A∗B=E,其中B是A的逆
所
以
E
−
A
k
E
−
A
∗
B
=
E
所以\frac{E-A^k}{E-A} \quad*B=E
所以E−AE−Ak∗B=E
B
就
是
最
终
结
果
,
并
且
A
k
=
0
B就是最终结果,并且A^k=0
B就是最终结果,并且Ak=0
化
简
式
子
最
后
B
=
E
−
A
化简式子最后B=E-A
化简式子最后B=E−A
就
是
对
矩
阵
全
体
取
负
,
对
角
线
加
1
即
可
就是对矩阵全体取负,对角线加1即可
就是对矩阵全体取负,对角线加1即可
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
ll a[1010][1010];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ll n,k;cin>>n>>k;
for(int i=1;i<=n;i++,cout<<endl)
for(int j=1;j<=n;j++)
{
ll x;
cin>>x;
if(i==j)cout<<1ll-x<<' ';
else cout<<-x<<' ';
}
return 0;
}
G. 数位操作1
题意:
给
一
个
整
数
n
(
n
<
=
1
e
10
)
给一个整数n(n<=1e10)
给一个整数n(n<=1e10)
找
到
一
个
最
小
的
数
a
n
s
(
a
n
s
>
9
)
找到一个最小的数ans(ans>9)
找到一个最小的数ans(ans>9)
a
n
s
需
要
满
足
他
的
每
一
位
上
数
的
乘
积
等
于
n
ans需要满足他的每一位上数的乘积等于n
ans需要满足他的每一位上数的乘积等于n
题解:
首
先
a
n
s
>
9
,
如
果
n
小
于
10
的
话
首先ans>9,如果n小于10的话
首先ans>9,如果n小于10的话
那
么
可
以
直
接
确
定
结
果
是
(
1
n
)
那么可以直接确定结果是(1n)
那么可以直接确定结果是(1n)
乘
积
能
组
成
n
的
数
,
肯
定
是
n
的
因
子
乘积能组成n的数,肯定是n的因子
乘积能组成n的数,肯定是n的因子
所
以
进
行
对
n
的
2
到
9
因
子
分
解
,
如
果
发
现
大
于
9
的
因
子
,
说
明
不
可
行
所以进行对n的2到9因子分解,如果发现大于9的因子,说明不可行
所以进行对n的2到9因子分解,如果发现大于9的因子,说明不可行
但
是
会
发
现
有
的
因
子
可
以
和
自
己
或
和
别
的
因
子
相
乘
但是会发现有的因子可以和自己或和别的因子相乘
但是会发现有的因子可以和自己或和别的因子相乘
我
们
需
要
留
下
的
是
最
小
值
尽
量
小
的
几
个
小
于
10
的
因
子
我们需要留下的是最小值尽量小的几个小于10的因子
我们需要留下的是最小值尽量小的几个小于10的因子
所
以
我
们
干
脆
直
接
倒
着
(
从
9
到
2
)
找
因
子
所以我们干脆直接倒着(从9到2)找因子
所以我们干脆直接倒着(从9到2)找因子
这
样
会
尽
量
让
多
出
来
的
不
会
被
乘
走
的
因
子
留
下
,
并
且
解
决
了
因
子
相
乘
还
是
在
10
以
内
的
问
题
这样会尽量让多出来的不会被乘走的因子留下,并且解决了因子相乘还是在10以内的问题
这样会尽量让多出来的不会被乘走的因子留下,并且解决了因子相乘还是在10以内的问题
然
后
找
到
所
有
因
子
倒
序
输
出
即
可
然后找到所有因子倒序输出即可
然后找到所有因子倒序输出即可
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int cnt[10];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ll n;
while(cin>>n){
vector<int> v;
if(n<10){cout<<1<<n<<endl;continue;}
for(int i=9;i>1;i--)
while(n%i==0)v.pb(i),n/=i;
if(n>9){cout<<-1<<endl;continue;}
reverse(all(v));
for(auto i:v)cout<<i;
cout<<endl;
}
return 0;
}
C. 港口
题意:
有
n
件
货
物
,
第
i
件
质
量
为
w
i
有n件货物,第i件质量为w_i
有n件货物,第i件质量为wi
可
以
对
从
第
i
件
到
第
j
件
的
质
量
进
行
加
一
或
减
一
可以对从第i件到第j件的质量进行加一或减一
可以对从第i件到第j件的质量进行加一或减一
问
至
少
多
少
次
能
让
全
部
货
物
质
量
相
等
问至少多少次能让全部货物质量相等
问至少多少次能让全部货物质量相等
题解:
纯
原
题
纯原题
纯原题
原题链接
这
个
是
运
用
了
差
分
这个是运用了差分
这个是运用了差分
对
于
每
一
件
货
物
求
出
他
和
上
一
个
货
物
的
差
值
对于每一件货物求出他和上一个货物的差值
对于每一件货物求出他和上一个货物的差值
如
果
想
让
全
部
相
等
,
就
是
让
这
些
差
值
都
变
为
0
如果想让全部相等,就是让这些差值都变为0
如果想让全部相等,就是让这些差值都变为0
对
于
每
次
区
间
加
操
作
,
区
间
内
部
的
差
值
不
会
改
变
对于每次区间加操作,区间内部的差值不会改变
对于每次区间加操作,区间内部的差值不会改变
会
改
变
的
就
是
两
端
和
外
部
的
会改变的就是两端和外部的
会改变的就是两端和外部的
比
如
差
分
数
组
为
b
,
区
间
L
到
R
加
1
比如差分数组为b,区间L到R加1
比如差分数组为b,区间L到R加1
那
么
b
L
+
+
,
b
R
+
1
−
−
那么b_L++,b_{R+1}--
那么bL++,bR+1−−
如
果
是
进
行
减
操
作
同
理
,
b
L
−
−
,
b
R
+
1
+
+
如果是进行减操作同理,b_L--,b_{R+1}++
如果是进行减操作同理,bL−−,bR+1++
所
以
问
题
转
化
,
对
差
分
数
组
进
行
多
少
次
如
下
操
作
让
数
列
全
部
变
成
0
所以问题转化,对差分数组进行多少次如下操作让数列全部变成0
所以问题转化,对差分数组进行多少次如下操作让数列全部变成0
对
于
2
<
=
i
,
j
<
=
n
,
b
i
+
+
,
b
j
−
−
对于2<=i,j<=n,b_i++,b_j--
对于2<=i,j<=n,bi++,bj−−
所
以
我
们
只
需
要
统
计
数
组
中
有
多
少
正
数
和
负
数
所以我们只需要统计数组中有多少正数和负数
所以我们只需要统计数组中有多少正数和负数
然
后
同
时
消
除
两
种
数
,
直
到
一
种
为
0
然后同时消除两种数,直到一种为0
然后同时消除两种数,直到一种为0
剩
余
多
出
来
的
数
全
部
和
1
进
行
操
作
,
使
得
全
部
为
0
即
可
剩余多出来的数全部和1进行操作,使得全部为0即可
剩余多出来的数全部和1进行操作,使得全部为0即可
另
x
为
正
数
和
,
y
为
负
数
和
另x为正数和,y为负数和
另x为正数和,y为负数和
列
出
式
子
就
是
m
i
n
(
x
,
y
)
+
a
b
s
(
x
−
y
)
=
m
a
x
(
x
,
y
)
列出式子就是min(x,y)+abs(x-y)=max(x,y)
列出式子就是min(x,y)+abs(x−y)=max(x,y)
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
ll b[maxn],a[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
ll x=0,y=0;
for(int i=1;i<=n;i++)b[i]=a[i]-a[i-1];
for(int i=2;i<=n;i++){
if(b[i]<0)y+=-b[i];
else x+=b[i];
}
cout<<max(x,y);
return 0;
}
F. 集合操作
题意:
有
n
次
操
作
,
操
作
分
为
3
种
有n次操作,操作分为3种
有n次操作,操作分为3种
1.
如
果
集
合
中
无
x
,
插
入
x
1.如果集合中无x,插入x
1.如果集合中无x,插入x
2.
如
果
集
合
有
有
x
,
删
除
x
2.如果集合有有x,删除x
2.如果集合有有x,删除x
找
到
>
=
x
的
最
小
的
集
合
中
没
有
的
数
找到>=x的最小的集合中没有的数
找到>=x的最小的集合中没有的数
题解:
n
<
=
1
e
6
,
x
<
=
1
e
9
n<=1e6,x<=1e9
n<=1e6,x<=1e9
由
于
是
要
找
一
个
没
有
的
数
由于是要找一个没有的数
由于是要找一个没有的数
如
果
暴
力
找
,
n
过
大
,
如
果
已
经
插
入
很
多
连
续
数
,
会
t
l
e
如果暴力找,n过大,如果已经插入很多连续数,会tle
如果暴力找,n过大,如果已经插入很多连续数,会tle
但
是
如
果
想
用
一
个
s
e
t
维
护
不
存
在
集
合
里
的
数
但是如果想用一个set维护不存在集合里的数
但是如果想用一个set维护不存在集合里的数
x
又
是
1
e
9
,
会
m
l
e
x又是1e9,会mle
x又是1e9,会mle
然
后
我
就
想
到
了
可
以
用
二
分
找
一
下
不
存
在
的
数
然后我就想到了可以用二分找一下不存在的数
然后我就想到了可以用二分找一下不存在的数
但
不
存
在
的
数
又
不
是
单
调
的
,
不
能
用
二
分
找
但不存在的数又不是单调的,不能用二分找
但不存在的数又不是单调的,不能用二分找
所
以
就
需
要
维
护
个
数
,
看
x
到
m
i
d
的
集
合
存
在
个
数
是
否
等
于
m
i
d
−
x
+
1
所以就需要维护个数,看x到mid的集合存在个数是否等于mid-x+1
所以就需要维护个数,看x到mid的集合存在个数是否等于mid−x+1
但
是
x
很
大
,
维
护
这
个
个
数
仍
然
会
m
l
e
但是x很大,维护这个个数仍然会mle
但是x很大,维护这个个数仍然会mle
所
以
我
们
就
需
要
对
这
些
x
进
行
离
散
所以我们就需要对这些x进行离散
所以我们就需要对这些x进行离散
将
每
个
x
和
他
的
下
一
个
点
放
入
数
组
,
由
于
需
要
表
示
中
间
的
间
隔
将每个x和他的下一个点放入数组,由于需要表示中间的间隔
将每个x和他的下一个点放入数组,由于需要表示中间的间隔
然
后
进
行
离
散
,
离
散
完
中
间
的
个
数
就
可
以
用
树
状
数
组
维
护
然后进行离散,离散完中间的个数就可以用树状数组维护
然后进行离散,离散完中间的个数就可以用树状数组维护
然
后
按
刚
才
的
思
路
进
行
二
分
查
找
即
可
然后按刚才的思路进行二分查找即可
然后按刚才的思路进行二分查找即可
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e6+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node{
int id,x;
}p[maxn];
int a[maxn],c[maxn];
int lowbit(int x){
return x&(-x);
}
void add(int x,int v){
while(x<maxn){
c[x]+=v;
x+=lowbit(x);
}
}
int query(int x){
int res=0;
while(x){
res+=c[x];
x-=lowbit(x);
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;cin>>n;
for(int i=1;i<=n;i++)
cin>>p[i].id>>p[i].x,a[2*i-1]=p[i].x,a[2*i]=p[i].x+1;
int len=2*n;
sort(a+1,a+1+len);
len=unique(a+1,a+1+len)-a-1;
for(int i=1;i<=n;i++){
int op=p[i].id;
int x=lower_bound(a+1,a+1+len,p[i].x)-a;
if(op==1){
if(!(query(x)-query(x-1)))add(x,1);
}
if(op==2){
if(query(x)-query(x-1))add(x,-1);
}
if(op==3){
int l=x,r=len,ans=-1;
while(l<=r){
int mid=l+r>>1;
if(query(mid)-query(x-1)>=mid-x+1)ans=mid,l=mid+1;
else r=mid-1;
}
if(ans!=-1)cout<<a[ans]+1<<endl;
else cout<<a[x]<<endl;
}
}
return 0;
}