C
题意:求这个排列的上一个排列。
直接用STL自带的求排列即可。
code:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second
const int N=2e5+10;
const double eps=1e-4;
typedef pair<int,int> pii;
int a[N];
void work()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
prev_permutation(a+1,a+1+n);
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
cout<<endl;
}
signed main()
{
int t;
//cin>>t;
t=1;
while(t--)
{
work();
}
return 0;
}
D
题意:给定数组A,每次可选则下列两种操作:
1.把
a
i
a_i
ai 变为
a
i
a_i
ai/2 .(
a
i
a_i
ai要为2的倍数)
2.把
a
i
a_i
ai 变为
a
i
a_i
ai/3 .(
a
i
a_i
ai要为3的倍数)
问能否通过这些操作,把A中元素变成相等的。
若可以,求出总的最小操作次数,若不可以,输出-1。
思路:我是贪心的做的,也就是把最小的一个数拿出来,分解到直到不能被2或3整除。然后看是否其他数能否最后也分解成这个数。
若可以分解为这个数,答案就是总的次数-共有的因子的数量,否则,答案为-1.
(代码其实还是有点丑陋,其实不用考虑那么多也行)
code:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second
const int N=2e5+10;
const double eps=1e-4;
typedef pair<int,int> pii;
int a[N];
int x[N],y[N];
void work()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int m;
while(a[1]){
if(a[1]%2==0){
a[1]/=2; x[1]++;
}
else if(a[1]%3==0){
a[1]/=3; y[1]++;
}
else {
m=a[1]; break;
}
}
for(int i=2;i<=n;i++){
while(a[i]!=m)
{
if(a[i]%2==0){
a[i]/=2; x[i]++;
}
else if(a[i]%3==0){
a[i]/=3; y[i]++;
}
else {
cout<<-1<<endl;
return ;
}
}
}
int ans=0;
int cnt1,cnt2;
cnt1=1e9,cnt2=1e9;
for(int i=1;i<=n;i++){
cnt1=min(cnt1,x[i]);
cnt2=min(cnt2,y[i]);
}
for(int i=1;i<=n;i++){
ans+=x[i]-cnt1;
ans+=y[i]-cnt2;
}
cout<<ans<<endl;
}
signed main()
{
int t;
//cin>>t;
t=1;
while(t--)
{
work();
}
return 0;
}
E
题意:有n*m的网格,给定起点和障碍物的位置,起点只有一个,问是否存在一条路,从起点出发,最后又回到起点,且路径长>=4.
直接进行dfs,如果能够找到一条路径就直接返回即可,同时为了防止每个点被遍历多次,要记录被遍历过的点。同时题目只告诉了n*m的范围,但没告诉n和m的范围,因此需将二维坐标映射成一维。
code:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define x first
#define y second
const int N=4e6+10;
const double eps=1e-4;
typedef pair<int,int> pii;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
int n,m;
char mp[N];
bool st[N];
int sx,sy;
int get(int i,int j)
{
return (i-1)*m+j;
}
bool dfs(int x,int y,int cnt)
{
for(int i=0;i<4;i++){
int a=dx[i]+x,b=dy[i]+y;
if(a==sx&&b==sy&&cnt>=4) return 1;
if(a<1||a>n||b<1||b>m||st[get(a,b)]||mp[get(a,b)]=='#') continue;
st[get(a,b)]=1;
if(dfs(a,b,cnt+1)) return 1;
}
return 0;
}
void work()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
char s;
cin>>s;
if(s=='S') {
sx=i,sy=j;
}
mp[get(i,j)]=s;
}
}
st[get(sx,sy)]=1;
if(dfs(sx,sy,1)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
signed main()
{
ios;
int t;
//cin>>t;
t=1;
while(t--)
{
work();
}
return 0;
}
F
题意:一共有n个球,值为
a
i
a_i
ai ,按顺序每次将一个球加入到箱子里,然后从箱子里有放回的拿出两个球,求max(
a
x
a_x
ax,
a
y
a_y
ay)的期望值。
思路:很明显暴力求解的话必然会超时,考虑优化,可以发现假设当前箱子有了3,6,5,2,1这几个求,要把4加进来,那么其对答案的贡献是什么呢? 应该是4本身, 加上里面
≤
\leq
≤ 4的球的个数x*4,再加上 大于4的所有球的值的和。 可以想到用树状数组来动态的维护两个值,一个是个数,一个是类似于前缀和的形式。
code:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define x first
#define y second
const int N=3e5+10,mod=998244353;
const double eps=1e-4;
typedef pair<int,int> pii;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
int a[N];
int tr[N],tr1[N];
int qmi(int a,int k)
{
int ans=1;
while(k)
{
if(k&1) ans=ans*a%mod;
a=a*a%mod;
k>>=1;
}
return ans;
}
int lowbit(int x)
{
return x&-x;
}
void add(int x,int c)
{
for(int i=x;i<N;i+=lowbit(i)) tr[i]+=c;
}
int sum(int x)
{
int ans=0;
for(int i=x;i;i-=lowbit(i)) ans+=tr[i];
return ans;
}
void add1(int x,int c)
{
for(int i=x;i<N;i+=lowbit(i)) tr1[i]+=c;
}
int sum1(int x)
{
int ans=0;
for(int i=x;i;i-=lowbit(i)) ans+=tr1[i];
return ans;
}
void work()
{
int n;
cin>>n;
int ans=0,tot=0;
for(int i=1;i<=n;i++){
cin>>a[i];
tot+=a[i];
add(a[i],1); add1(a[i],a[i]);
int x=sum(a[i]),y=tot-sum1(a[i]);
//cout<<x<<"####"<<y<<endl;
ans=(ans+(2*(x-1)*a[i]%mod+2*y+a[i]))%mod;
int p=i*i%mod;
cout<<ans*qmi(p,mod-2)%mod<<endl;
}
}
signed main()
{
ios;
int t;
//cin>>t;
t=1;
while(t--)
{
work();
}
return 0;
}