【A 转圈游戏】
【解题方法】很水的题,直接给代码了!
【AC code】
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long int LL;
LL solve(LL a,LL n,LL mod)
{
LL res=1;
LL temp=a;
for(;n;n/=2)
{
if(n%2==1)
res=(res*temp)%mod;
temp=((temp%mod)*(temp%mod))%mod;
}
return res;
}
int main()
{
LL n,m,k,x;
while(~scanf("%I64d%I64d%I64d%I64d",&n,&m,&k,&x))
{
LL len=solve(10,k,n);
//cout<<len<<endl;
LL ans=x+m*len;
ans=ans%n;
printf("%lld\n",ans);
}
return 0;
}
【B 火柴排队】
【解题方法】实际上就是维护一个逆序对!用树状数组去求就行啦!不懂这种方法的可以参考这篇点击打开链接
【AC code】
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const int mod=99999997;
const int maxn=100005;
int low_bit(int i)
{
return i&(-i);
}
int n;
int c[maxn];
int d[maxn];
struct node{
int val,pos;
friend bool operator<(const node &a,const node &b)
{
return a.val<b.val;
}
}A[maxn],B[maxn];
void update(int i,int v)
{
while(i<=n)
{
d[i]+=v;
i+=low_bit(i);
}
}
int getsum(int i)
{
int res=0;
while(i){
res+=d[i];
i-=low_bit(i);
}
return res;
}
int main()
{
int x;
while(~scanf("%d",&n))
{
memset(d,0,sizeof(d));
LL ans=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&A[i].val);
A[i].pos=i;
}
for(int i=1; i<=n; i++)
{
scanf("%d",&B[i].val);
B[i].pos=i;
}
sort(A+1,A+n+1);
sort(B+1,B+n+1);
for(int i=1; i<=n; i++)
{
c[B[i].pos]=A[i].pos;
}
for(int i=1; i<=n; i++)
{
update(c[i],1);
ans+=(i-getsum(c[i]));
ans%=mod;
}
printf("%lld\n",(ans+mod)%mod);
}
return 0;
}
【C 积木大赛】
【题意】点击打开链接
【解题方法】就是个非常简单的贪心,不过比赛的时候看了好久才看出来!
【AC code】
#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
int a[maxn];
int b[maxn];
int main()
{
int n;
// int ans=0;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(int i=1; i<=n; i++)
{
b[i]=a[i];
}
for(int i=2; i<=n; i++)
{
b[i]=b[i]-min(a[i],a[i-1]);
}
// for(int i=1; i<=n; i++)
// {
// cout<<b[i]<<" ";
// }
int ans=0;
for(int i=1; i<=n; i++)
{
ans+=b[i];
}
cout<<ans<<endl;
}
【D 花匠】
【题意】点击打开链接
【解题方法】有两种解题方法,一种是DP.令S[i][1]表示以i为结尾,且降序到达a[i]的最长抖动序列长度;令S[i][0]表示以i为结尾,且升序到达a[i]的最长抖动序列长度。
(1)a[i+1]>a[i]:
S[i+1][0]=max(S[i][1]+1,S[i][0]);
S[i+1][1]=S[i][1];
(2)a[i+1]<a[i]:
S[i+1][0]=S[i][0];
S[i+1][1]=max(S[i][0]+1,S[i][1]);
(3)a[i+1]= =a[i]:
S[i+1][0]=S[i][0];
S[i+1][1]=S[i][1];
【初始化】 S[1][0]=S[1][1]=1.
【AC code】
【方法二】实际上这题是一道贪心题,答案就是 转择点的个数。这种方法的代码如下:
【AC code】
#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
int dp[maxn][2];//dp[i][0]以i结尾,升序到达a[i]
int a[maxn];
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
dp[1][0]=1;
dp[1][1]=1;
for(int i=2; i<=n; i++)
{
if(a[i]>a[i-1])
{
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+1);
dp[i][1]=dp[i-1][1];
}
else if(a[i]<a[i-1])
{
dp[i][0]=dp[i-1][0];
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+1);
}
else
{
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][1];
}
}
int ans=max(dp[n][0],dp[n][1]);
printf("%d\n",ans);
}
return 0;
}
【方法二】实际上这题是一道贪心题,答案就是 转择点的个数。这种方法的代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
int a[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
int flag=-1;
int ans=1;
for(int i=2; i<=n; i++)
{
if(a[i]>a[i-1])
{
if(flag!=1)
{
ans++;
flag=1;
}
}
if(a[i]<a[i-1])
{
if(flag!=0)
{
ans++;
flag=0;
}
}
}
printf("%d\n",ans);
return 0;
}