如果有什么讲的不清楚的欢迎留言私信交流~
文章目录
A - Filling Diamonds
题意:问n个菱形方块拼成所示的钻石的方案。
思路: 很明显的是每个图形中有n个站着的菱形,选择其中一个其他都会变成躺着的,因此答案为n。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#define mp make_pair
#define pb push_back
#define ll long long
#define kl k<<1
#define kr k<<1|1
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
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;}
void put1(){ puts("YES") ;}void put2(){ puts("NO") ;}void put3(){ puts("-1"); }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a =
(a*a)%p;b >>= 1;}return ans%p;}
const int manx=1e5+5;
const int mo=998244353;
ll n;
int main(){
ll p=read();
while(p--){
cin>>n;
cout<<n<<endl;
}
return 0;
}
B - Sorted Adjacent Differences
题意:给你一个数组,你需要重新排列这个数组的元素,使得相邻两个元素的差值呈非递减。
思路:为了保持每两个数之间的间隔变大,可以选择排序后从
(
n
+
1
)
/
2
(n+1)/2
(n+1)/2 开始,偶数情况下右边会多一个所以
w
h
i
l
e
while
while里面先输出右边再输出左边,这样保证间隔来回递增。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#define mp make_pair
#define pb push_back
#define ll long long
#define kl k<<1
#define kr k<<1|1
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
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;}
void put1(){ puts("YES") ;}void put2(){ puts("NO") ;}void put3(){ puts("-1"); }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a =
(a*a)%p;b >>= 1;}return ans%p;}
const int manx=1e5+5;
const int mo=998244353;
ll a[manx];
ll n;
int main(){
ll p=read();
while(p--){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
ll mid=(n+1)/2;
sort(a+1,a+1+n);
cout<<a[mid];
ll l=mid-1,r=mid+1;
while(l!=0 || r!=n+1){
if(r!=n+1) cout<<" "<<a[r++];
if(l!=0) cout<<" "<<a[l--];
}
cout<<endl;
}
return 0;
}
C - Powered Addition
题意:给你一个数组,你可以在第x秒选一些元素让它们都加上 2 的 ( x − 1 ) 幂 2的(x−1)幂 2的(x−1)幂 ,问至少需要多少秒可以使数组变成非递减的数组。
思路:找到最大的间隔,然后枚举 x 进行累加就可以了。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#define mp make_pair
#define pb push_back
#define ll long long
#define kl k<<1
#define kr k<<1|1
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
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;}
void put1(){ puts("YES") ;}void put2(){ puts("NO") ;}void put3(){ puts("-1"); }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a =
(a*a)%p;b >>= 1;}return ans%p;}
const int manx=1e5+5;
const int mo=998244353;
ll a[manx];
ll n;
int main(){
ll p=read();
while(p--){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
ll mi=a[n],ma=0;
for(int i=n-1;i>=1;i--){
if(a[i]>mi) ma=max(ma,a[i]-mi);
mi=min(mi,a[i]);
}
ll x=1,cnt=0;
if(!ma) cout<<0<<endl;
else{
while(ma>0){
++cnt; ma-=x; x<<=1;
}
cout<<cnt<<endl;
}
}
return 0;
}
D - Edge Weight Assignment
题意:问给一棵无根树每一条边赋值,要求任意两个叶子节点的路径上的边的权值异或和为0,求填写方案中权值种类的最大值和最小值。
思路:
- 先给出结论再解释:
- 如果叶子节点的深度有奇有偶,那么最小值为3,否则为1;
- 最大值为 n − 1 − x n-1-x n−1−x,x为连接与同一节点的超过1的叶子数目。
- 首先讲一下最小值,如果叶子节点的深度都为偶数/奇数,那么任意两个叶子间的距离为偶数(偶数+偶数=偶数 奇数+奇数=偶数),则可全1;否则的话只要两个叶子间距离为奇数,那么无法全1,只要选择3个叶子节点为1 2 3,其他全1;
- 最大值的话,不难想到n个点只有n-1条边,那么最大值可定为n-1,但是如果一个节点 fa 如果连接多个叶子的话,而且这些叶子之间只隔着两条边,所以这些叶子到 fa 的边权都是相同的 。那么说明假设 一个节点连接 x (x>1) 个叶子,那么就有x条边相同,因此最大值要减去这一部分的贡献,所以最大值为 n − 1 − x n-1-x n−1−x,x为连接与同一节点的超过1的叶子数目。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#define mp make_pair
#define pb push_back
#define ll long long
#define kl k<<1
#define kr k<<1|1
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
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;}
void put1(){ puts("YES") ;}void put2(){ puts("NO") ;}void put3(){ puts("-1"); }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a =
(a*a)%p;b >>= 1;}return ans%p;}
const int manx=1e5+5;
const int mo=998244353;
vector<ll>g[manx],fa;
ll n,ji,ou;
ll d[manx];
void dfs(ll u,ll pre){
d[u]=d[pre]+1;
for(auto v: g[u]){
if(v==pre) continue;
dfs(v,u);
}
if(g[u].size()==1){
if(d[u]&1) ji++;
else ou++;
if(pre==0) fa.pb(g[u][0]);
else fa.pb(pre);
}
}
int main(){
n=read();
for(int i=1;i<n;i++){
ll u=read(),v=read();
g[u].pb(v); g[v].pb(u);
}
dfs(1,0);
if(ji&&ou) cout<<3<<" ";
else cout<<1<<" ";
ll ma=n-1;
sort(fa.begin(),fa.end());
for(int i=1;i<fa.size();i++)
if(fa[i]==fa[i-1]) --ma;
cout<<ma;
return 0;
}
以上,如果有什么讲的不清楚的欢迎留言私信交流~