A
题目描述小Why有一个 2 行 2 列的方阵 A,每个格子上都有一个数字。
小Why可以执行以下的操作至多一次:
修改任意一个格子上的数字。
小Why想知道他能否使得这个方阵每行每列之和相等。
输入描述:
以下两行,每行两个元素,其中第 iii 行第 jjj 列的元素为 Ai,j (0≤Ai,j≤9)。
输出描述:
如果小Why能够使得方阵 A 每行每列之和相等,那么输出 "YES" (不含引号),否则输出 "NO" (不含引号)。示例1
输入
9 7 7 7输出
YES示例2
输入
1 2 3 4输出
NO
#include
using namespace std;
#define int long long
#define fp(i,a,b) for(int i=a;i<=b;++i)
const int N=1e6+10;
typedef double db;
int a,b,c,d;
signed main()
{
cin>>a>>b>>c>>d;
int cnt=0;
if(a==d)cnt++;
if(b==c)cnt++;
if(cnt>=1){
cout<<"YES";
}
else{
cout<<"NO";
}
return 0;
}
// a b c d a+b=c+d=a+c=b+d b=c a=d
B
题目描述
小Why有一个长度为 n 的全排列 a,定义px 表示元素 x 在 a 中的下标。
小Why先将上述 n 个元素映射为图 G 中的点,之后对于每个点 x ,都向 px 连一条边。在完成这些操作后,图 G 中一共出现了 m 个环(包括自环)。
现在小Why告诉你可以对 a 执行以下操作任意多次:
选择 a 中任意两个不同的元素,交换它们的位置。
小Why只打算告诉你 n 和 m,他想考考你至少需要多少次操作才能使得 a 单调递增。
输入描述:
第一行包含两个整数 n,m (1≤m≤n≤10^9),表示图 G 中点的个数和环的个数。输出描述:
输出一个整数,表示最少操作次数。示例1
输入
2 1输出
1
#include
using namespace std;
#define int long long
#define fp(i,a,b) for(int i=a;i<=b;++i)
const int N=1e6+10;
typedef double db;
int n,m;
signed main()
{
cin>>n>>m;
cout<
C
超市里一共有 n 个货架,m 个商品,一开始商品的位置是被打乱的,小Why需要将商品全部归位。
小Why在给货架编号后,实现了每个商品所在货架必然在其应在货架之前。
小Why决定手推购物车按编号顺序依次访问每个货架。在访问货架时,小Why可以执行以下两个操作任意多次:
当购物车不为空时,将购物车中的一个商品放上货架。
当货架不为空时,将货架上的一个商品放入购物车。
当小Why跑完一趟后,如果仍有商品没被归位,那么小Why会再次返回 1 号货架重复以上过程。
超市里的购物车同一时刻最多能放 k 个商品,且每个货架容量无限,请你告诉小Why至少需要跑多少趟才能将商品全部归位。输入描述:
第一行包括三个整数 n,m,k (2≤n≤10^6,1≤m,k≤10^6),表示货架个数,商品个数和购物车容量。
接下来 m 行,每行有两个整数 sti,edi(1≤sti
输出描述:
输出一个整数,表示最少需要的趟数。示例1
输入
3 3 1 1 2 1 3 2 3输出
2
#include
using namespace std;
#define int long long
#define fp(i,a,b) for(int i=a;i<=b;++i)
const int N=1e6+10;
typedef double db;
int n,m,k;
int a[N];
signed main()
{
cin>>n>>m>>k;
fp(i,1,m){
int x,y;
cin>>x>>y;
a[x]++,a[y]--;
}
int mmax=0;
fp(i,1,n)
{
a[i]+=a[i-1];
mmax=max(mmax,a[i]);
}
cout<<(mmax-1)/k+1;
return 0;
}
思路:可以抽象为差分
对于一个商品假设一开始在1,然后要去4
那么他在1-3这个区间就一定会占据一个购物车位置,因为在这期间不可能将它放下来
这样就可以直接通过差分来维护在商品的“占据情况”。
D
题目描述
小Why拿到了一个密码长度为 m 的密码锁,这个密码锁可输入内容无限,并只对最后输入的 m 位字符进行检测,检测正确时密码锁会解锁一次,同时清空包含检测正确字符串在内的之前的所有字符。
小Why输入了一个长度为 n 的字符串 s 后,密码锁一共解锁了 k 次,请你告诉他有多少种密码是可能正确的。
输入描述:
第一行包含三个整数 n,m,k (1≤m∗k≤n≤106),表示字符串 s 的长度,密码长度和解锁次数。第二行包含一个长度为 n 的字符串 s,保证字符串 s 中只含有 0∼9 的数字。输出描述:
输出一个整数,表示有多少种密码是可能正确的。示例1
输入
13 5 2 1231234123123输出
2
我复习了一波字符串哈希 这个算法我老早忘记了 以至于蓝桥杯差了这个就国三。哭死
字符串哈希模板:
#include
using namespace std;
//#define int long long
#define fp(i,a,b) for(int i=a;i<=b;++i)
const int N=1e6+10;
typedef double db;
typedef unsigned long long ULL;
int n,m;
int l1,r1,l2,r2;
const int pp=131;
ULL h[N];
ULL p[N];
string s;
ULL gets(int a,int b)
{
return h[b]-h[a-1]*p[b-a+1];
}
int main()
{
cin>>n>>m;
cin>>s;
s=" "+s;
p[0]=1;
for(int i=1;i<=n;i++)
{
h[i]=h[i-1]*pp+s[i];
p[i]=p[i-1]*pp;
}
for(int i=1;i<=m;i++){
cin>>l1>>r1>>l2>>r2;
if(gets(l1,r1)==gets(l2,r2)){
cout<<"Yes"<<"\n";
}
else{
cout<<"No"<<"\n";
}
}
return 0;
}
这道题也是字符串哈希 用map记录一下就行
#include
using namespace std;
//#define int long long
#define fp(i,a,b) for(int i=a;i<=b;++i)
const int N=1e6+10;
typedef double db;
typedef unsigned long long ULL;
int n,m,k;
const int pp=131;
ULL h[N];
ULL p[N];
string s;
ULL gets(int a,int b)
{
return h[b]-h[a-1]*p[b-a+1];
}
mapma;
maplast;
int main()
{
cin>>n>>m>>k;
cin>>s;
s=" "+s;
p[0]=1;
for(int i=1;i<=n;i++)
{
h[i]=h[i-1]*pp+s[i];
p[i]=p[i-1]*pp;
}
for(int i=1;i<=n;i++){
if(i>=m){
ULL g=gets(i-m+1,i);
if(!last.count(g)||last[g]<=i-m){
ma[g]++;
last[g]=i;
}
}
}
int sum=0;
for(auto x:ma){
if(x.second==k){
sum++;
}
}
cout<