水平有限,只打了三题比较简单的模拟题;
a.题目大意:任意倒转两个字符使字典序更小,找到字典序相反的两个,直接倒转就好,复杂度O(n);
#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int main()
{
int n;
scanf("%d",&n);
string s;
cin>>s;
for(int i=1;i
b.题意,给出一个连续的数字,数字长度>13,V和P轮流删除一个数,当删除到是十一位时,停止操作。然后问
V先操作时,最后的数字是否以8开头。是则输出yes否则no;
题解:我是直接模拟了,贪心,V肯定删除从左到右第一个不是8的数,P肯定删除从左到右最先出现的8;
还有一种做法是统计最后10个数字之前的8的个数,看看操作轮数是否大于8的个数,大于则no;
当时没想到,就直接模拟了,所以代码比较丑
#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int main()
{ int n;
scanf("%d",&n);
bool vis[100005];
memset(vis,true,sizeof(vis));
vectorq;
string s;
cin>>s;
int flag=1;
int q1=0,q2=0;
for(int i=0;i<(s.size()-11)&&q1
c
题意:有一个闹钟,给出n个时间,和m个时间间隔。要求你选择一个开始的时间y与一个间隔p;
那么从y开始每隔p个时间间隔就闹钟会响一次,需要在给出的n个时间点上,闹钟都会想;
题解:找出n个时间的差,然后对差取最小公因数g,然后从间隔中判断,是否存在一个间隔p,使得g%p==0;
输出任意答案;
#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
const int maxn=3e5+10;
ll arr[maxn];
ll brr[maxn];
ll crr[maxn];
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
ll gg;
int cnt=0;
up(i,1,n)
{
if(i==1)scanf("%I64d",&arr[i]);
else
{ scanf("%I64d",&arr[i]);
crr[++cnt]=arr[i]-arr[i-1];
}
}
if(cnt==1)
{
gg=crr[1];
}
else
{
gg=gcd(crr[1],crr[2]);
up(i,3,cnt)
{
gg=gcd(crr[i],gg);
}
}
int flag=0;
up(i,1,m)
{
scanf("%I64d",&brr[i]);
if(gg%brr[i]==0)
{
flag=i;
}
}
if(flag)
{
cout<<"YES"<
d题
题意,给出一个n,m;与长度为n的数组
可以进行一个操作,就是对于长度为n的数组的连续子序列可以乘上m。然后再求,最大子序列和;
这题用DP的思想,考虑当前位置状态,一共有三种;
1.处于处理区间前
2.处于处理区间中
3.处于处理区间外
所以需要3个dp数组,dp[i][3]//i表示从1开始的区间到i的最大子序列和
然后可以得出下面的状态方程
dp[i][0]=max(dp[i-1][0],0ll)+a[i];//0状态表示可以开始新的处理
dp[i][1]=max(dp[i-1][0],max(dp[i-1][1],0))+a[i]*1ll*m//1状态表示处于处理的区间
dp[i][2]=max(max(dp[i-1][0],d[i-1][2]),max(dp[i-1][1],0ll))+a[i];状态表示处理完毕,即后面不可处理
注意的就是,当当前区间的最大子序列和小于0的时候,我们可以直接取0,以及在max中,数据类型必须相同;
#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
const int maxn=3e5+10;
ll dp[maxn][3];//i表示从1开始的区间到i的最大字段和
ll arr[maxn];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
up(i,1,n)cin>>arr[i];
ll ans=0;
up(i,1,n)
{
dp[i][0]=max(dp[i-1][0],0ll)+arr[i];//0状态表示可以开始新的操作
dp[i][1]=max(max(dp[i-1][1],0ll),dp[i-1][0])+arr[i]*m;//1状态表示处于倒转的区间
dp[i][2]=max(max(dp[i-1][0],0ll),max(dp[i-1][1],dp[i-1][2]))+arr[i];//2状态表示倒转完毕,即后面不可倒转
ans=max(ans,dp[i][0]);
ans=max(ans,dp[i][1]);
ans=max(ans,dp[i][2]);
}
cout<
后面的···不会了,努力补题ing!!!