https://codeforces.com/contest/1096
https://codeforces.com/contest/1096/problem/B
题解:
比如aacdeee
如果我们想保留左边的a 话 那么需要删除的是aa后面的所有,以及一个a, 连续的a 的长度为2 可删除的为 cdeee acdeee 两种
如果想保留右边e的话 那么要删除的是右边aacd 然后 和两个e 一共三种删除方法。
所以左右不等于的时候 删除方法就很明显了
第二种情况 eecdeee
左边连续2 右边连续3
其实就可以这么理解 左边2个位置 右边 3个位置 左边选一个 右边选一个 和不保留左边或者字符的 2 + 3 种方法。
比如 删除 ecde 和删除 eecd 就是左边保留字符的删除方法和不保留字符的删除方法
#include <iostream>
#include <cstring>
using namespace std;
#define int long long
#define mod 998244353
signed main(){
//cout << "Hello world!" << endl;
int n;
cin>>n;
string s;
cin>>s;
int l=1;
int r=1;
for(int i=0;i<n;i++){/*左边最长长度*/
if(s[i]==s[i+1])
l++;
else
break;
}
for(int i=n-1;i>=0;i--){/*右边最长长度*/
if(s[i]==s[i-1])
r++;
else
break;
}
int ans=1;/*全删*/
if(s[0]==s[n-1])/*左右相等话复杂一点,删除中间那一段也是一次,自己画画吧*/
ans+=(r+l+r*l)%mod;/* r*l 左右不用贴着删,但是至少要保留一个字符*/
else/*左右不等很简单,自己模拟一遍*/
ans+=(l+r)%mod;/*贴着左边依次往右扩展(r),贴着右边依次往左边扩展(l)*/
cout<<ans<<endl;
return 0;
}
https://codeforces.com/contest/1096/problem/C
题意:
给定一个角度 θθ,请你寻找一个正 nn 边型,满足在这个正 nn 边型上找三个顶点 A,B,CA,B,C (可以不相邻),使得 ∠ABC = θ∠ABC = θ 。请输出最小的 nn。保证 nn 不超过 998244353998244353。多组数据。
注意给出的 θθ 是使用角度制表示的。
题解:
数学公式了
首先 n边形的一个内角度数为
180-360/n = (180 n -360) /n = 180*(n-2)/n ;
然后 多边形的一个内角 可以被 等分为n-2 个 这点可以画图证明
设内角 大小 180*(n-2)/n =x; 需要查找的角度为y
x/(n-2) = y /d d为x/(n-2) 的倍数
之后 公式化简 变成 180*d / y= n
这里证明 180 *d 必须是y 的整数倍数
所以只需要求 180 和 y 的最小公倍数 然后除以 y 的结果就是 n的一个公约数 了
之后去让检查这个n是否符合内角的大小- - 然后循环
比如 178 和 180 寻找到的n 是90 但是 实际上是180
原因就是 90 的内角是 176度 少于178° 。
#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a,long long b)
{
return b==0?a:gcd(b,a%b);
}
long long lcm(long long a,long long b)
{
return a*b/gcd(a,b);
}
int main()
{
long long t;
cin>>t;
while(t--)
{
long long ss;
cin>>ss;
long long lc=lcm(180,ss);
int n=lc/ss,ns=lc/ss;
int q=1;
while(180*(n-2)/n<ss) n=ns*q++ ; //判断是否符合内角的大小
cout<<n<<endl;
// cout<<lc/n<<endl;
}
}
https://codeforces.com/contest/1096/problem/D
题意:长度为n的字符串 删除每个位置的字符有花费 求使其没有hard的子序列的最小花费
题解:
四种字符只需要删除其中任意一种就可以保证无法构成hard
四种字符的次序也是固定的 , 所以 我们当碰到第一个时 才需要注意第二个 碰到第二个时,才需要注意第三个
依次类推,
所以dp方程就是
dp[x]=min(dp[x-1],dp[x]+a[i]);
#include <bits/stdc++.h>
using namespace std;
long long dp[100005],a[100005];
int main()
{
long long n;
while(cin>>n)
{
string s;
cin>>s;
memset(dp,0,sizeof(dp));
for(long long i=0;i<n;i++) cin>>a[i];
for(long long i=0; i<n; i++)
{
if(s[i]=='h')
{
dp[1]=dp[1]+a[i];
}
else if(s[i]=='a')
{
dp[2]=min(dp[1],dp[2]+a[i]);
}
else if(s[i]=='r')
{
dp[3]=min(dp[2],dp[3]+a[i]);
}
else if(s[i]=='d') dp[4]=min(dp[3],dp[4]+a[i]);
}
cout<<min( min(dp[1],dp[2]),min(dp[3],dp[4]) ) <<endl;
}
}