由于我熬夜的时候解题效率很差,因此在决定开始打CF之后,尽量在比赛后的第二天拉一套题在VJ上面做,就当成练习题做,因为比赛的话自己水平还比较低,先多做Div3,这个比赛是我第一次做div3,做了三道,补了两道(比较菜的那种)E题待补
You are given two positive integers a and b.In one move, you can change a in the following way:Choose any positive odd integer x (x>0) and replace a with a+x;choose any positive even integer y (y>0) and replace a with a−y.You can perform as many such operations as you want. You can choose the same numbers x and y in different moves.Your task is to find the minimum number of moves required to obtain b from a. It is guaranteed that you can always obtain b from a.You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤104) — the number of test cases.Then t test cases follow. Each test case is given as two space-separated integers a and b (1≤a,b≤109).
Output
For each test case, print the answer — the minimum number of moves required to obtain b from a if you can perform any number of moves described in the problem statement. It is guaranteed that you can always obtain b from a.
1.题目大意:给出两个数a,b,每次可以对a或b加减任意数,求最少多少步可以使a,b相等
2.直接模拟即可,我们发现,先求出二者的差值,那么再分别对其正负情况考虑是奇偶性。最多两步就能得到答案
代码:
#include <iostream>
#include <math.h>
using namespace std;
int a,b,t;
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d%d",&a,&b);
int c=b-a;
if(c>0){
if(c&1) printf("1\n");
else printf("2\n");
}else if(c<0){
c=abs(c);
if(c&1) printf("2\n");
else printf("1\n");
}else printf("0\n");
}
return 0;
}
You are given an array a of length n.You are also given a set of distinct positions p1,p2,…,pm, where 1≤pi Input Output 1.题目大意,给出一个大小为n的1-n的序列a,再给出一个数组p,p数组的每个数代表p的下标,意思是a数组下标p和p+1可以交换位置。求在指定交换序列下,a数组能否变为升序 2.如果a序列变为升序,那么每一个元素的后继一定比它大1,这里我想的是BFS,每一次将所有不符合的节点入队,接下来一次性把入队的节点都按照条件交换,然后判断是否升序成功。当队列空了如果还没成功就代表无法得到 代码: You want to perform the combo on your opponent in one popular fighting game. The combo is the string s consisting of n lowercase Latin letters. To perform the combo, you have to press all buttons in the order they appear in s. I.e. if s=“abca” then you have to press ‘a’, then ‘b’, ‘c’ and ‘a’ again.You know that you will spend m wrong tries to perform the combo and during the i-th try you will make a mistake right after pi-th button (1≤pi Input Output 1.题目大意:给出一串字符(a-z),每次下面给出一个序列。从字符串的第一个节点开始按,每次按到序列的第i个元素,就返回第一个字母。当这个序列按完之后就额外从头按到尾,求在按的过程中所有字母出现的次数 2.对于序列a[i],实际上就是对字符串前a[i]个都按一次,即区间都加一,而且我们最后要求的是每个节点的次数,显然是树状数组。首先我们引入差分的概念:差分即相邻两个数的差,由a数组我们能得到a的差分数组d[i]=a[i]-a[i-1],还可以得到二者之间的关系: 代码: https://blog.csdn.net/qq_44691917/article/details/104539224 题目链接 You are given two integers n and d. You need to construct a rooted binary tree consisting of n vertices with a root at the vertex 1 and the sum of depths of all vertices equals to d.A tree is a connected graph without cycles. A rooted tree has a special vertex called the root. A parent of a vertex v is the last different from v vertex on the path from the root to the vertex v. The depth of the vertex v is the length of the path from the root to the vertex v. Children of vertex v are all vertices for which v is the parent. The binary tree is such a tree that no vertex has more than 2 children.You have to answer t independent test cases. Input Output 1.题目大意:给出节点个数去构造二叉树,求是否能构造出深度和为d的二叉树。刚开始我写的是剪枝+搜索,结果超时了,原来是我没怎么计算时间复杂度,5000个节点即使剪枝也会超时的,如果有几百个节点可以试一下爆搜 2.看别人思路,原来是这样:链状的二叉树总深度一定是最大的,然后完全二叉树总深度是最小的,那么我们就先假设构成一条链,看看能否一步步移动节点构成需要的二叉树。首先每层节点选择一个代表并标记,然后从大到小将未标记的节点作为本层代表的子节点,若当层代表还有其他子节点,继续下移。直到移动到最后一层后自己作为新一层的代表并标记即可 3.代码不太好写,下面别人的代码还不是很懂,等以后再研究研究(最近事情好多) https://blog.csdn.net/qq_44691917/article/details/104539711
The first line of the input contains one integer t (1≤t≤100) — the number of test cases.Then t test cases follow. The first line of each test case contains two integers n and m (1≤m
For each test case, print the answer — “YES” (without quotes) if you can sort the initial array in non-decreasing order (a1≤a2≤⋯≤an) using only allowed swaps. Otherwise, print “NO”.#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int a[105],vis[105];
int t,n,m,x;
queue<int> q;
bool check(){
int flag=1;
for(int i=2;i<=n;i++)
if(a[i]<a[i-1]){
q.push(i);
flag=0;
}
if(flag) return true;
else return false;
}
bool bfs(){
while(!q.empty()) q.pop();
if(check()) return true;
while(!q.empty()){
int MAX=q.size(); //一定要一次性操作完上一次入队的所有节点
while(MAX--){
int u=q.front();q.pop();
if(!vis[u-1]) return false;
swap(a[u-1],a[u]);
}
if(check()) return true;
}
return true;
}
int main()
{
scanf("%d",&t);
while(t--){
memset(vis,0,sizeof vis);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
while(m--){
scanf("%d",&x);
vis[x]=1;
}
if(bfs()) printf("YES\n");
else printf("NO\n");
}
return 0;
}
C - Perform the Combo (差分+树状数组)
The first line of the input contains one integer t (1≤t≤104) — the number of test cases.Then t test cases follow.The first line of each test case contains two integers n and m (2≤n≤2⋅105, 1≤m≤2⋅105) — the length of s and the number of tries correspondingly.The second line of each test case contains the string s consisting of n lowercase Latin letters.The third line of each test case contains m integers p1,p2,…,pm (1≤pi
For each test case, print the answer — 26 integers: the number of times you press the button ‘a’, the number of times you press the button ‘b’, …, the number of times you press the button ‘z’.
a[i]=d[1]+…+d[i]
那么我们会发现,如果对一个区间[x,y]内的所有数都执行加法,那么显然只有d[x]和d[y+1]的值会改变,[x+1,y]区间的值都不变。因此我们用d数组维护树状数组,当我们进行区间加法时,很明显只用更新d[x]和d[y+1],即d[x]+k,d[y+1]-k#include <iostream>
#include <string>
#include <cstring>
using namespace std;
#define lowbit(x) (x&(-x))
const int maxn=2e5+10;
int a[maxn],t[maxn],ans[30];
int T,m,n,x;
string s;
void update(int i,int k){
while(i<=n){
t[i]+=k;
i+=lowbit(i);
}
}
int ask(int i){
int ans=0;
for(;i;i-=lowbit(i)){
ans+=t[i];
}
return ans;
}
int main()
{
scanf("%d",&T);
while(T--){
memset(t,0,sizeof t);
memset(ans,0,sizeof ans);
scanf("%d%d",&n,&m);
cin>>s;
for(int i=0;i<s.size();i++){
a[i+1]=s[i]-'a';
}
while(m--){
scanf("%d",&x);
update(1,1);
update(x+1,-1);
}
update(1,1);
update(n+1,-1);
for(int i=1;i<=n;i++){
ans[a[i]]+=ask(i);
}
for(int i=0;i<26;i++){
printf("%d%c",ans[i],i==25?'\n':' ');
}
}
return 0;
}
D - Three Integers (枚举)
E - Construct the Binary Tree (思维)
The first line of the input contains one integer t (1≤t≤1000) — the number of test cases.The only line of each test case contains two integers n and d (2≤n,d≤5000) — the number of vertices in the tree and the required sum of depths of all vertices.It is guaranteed that the sum of n and the sum of d both does not exceed 5000 (∑n≤5000,∑d≤5000).
For each test case, print the answer.If it is impossible to construct such a tree, print “NO” (without quotes) in the first line. Otherwise, print “{YES}” in the first line. Then print n−1 integers p2,p3,…,pn in the second line, where pi is the parent of the vertex i. Note that the sequence of parents you print should describe some binary tree.#include<bits/stdc++.h>
using namespace std;
const int N=5005+5;
int t,n,m,l,r,sum[N],dep[N];
bool solve(){
fill(dep+1,dep+n+1,1);
m=n*(n-1)/2-m;
for(l=2,r=n;l<r;r--){
while(l<r && (m-r+l<0 || dep[l]==dep[l-1]*2)) l++;
if(l>=r) break;
m-=r,dep[r]--;
m+=l,dep[l]++;
}
return m==0;
}
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
if(!solve()) printf("NO\n");
else{
printf("YES\n");
for(int i=1;i<=r;++i)
sum[i]=sum[i-1]+dep[i];
for(int i=2;i<=r;++i){
for(int j=0;j<dep[i];++j)
printf("%d ",sum[i-2]+1+j/2);
}
printf("\n");
}
}
return 0;
}
/* 剪枝搜索超时了
#include
F - Moving Points (树状数组+离散化)