A
贪心 or dp,我们以dp[ i ] 表示 i 之前的最小回文串的个数,那么对于s[i+1],如果s[i + 1]+s[ i ]+s[ i - 1]+…+s[ j ]是一个回文串,那么dp[ i+1 ] = min(dp[ i+1 ],dp[ j - 1 ] + 1),特别的,dp[0] = 0;很明显,答案即是dp[length] - 1
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int dp[1010];
int main()
{
ios::sync_with_stdio(false);
int t;
string s;
cin>>t;
while (t --)
{
cin>>s;
dp[1] = 1,dp[0] = 0;
for (int i = 1;i < s.size();i ++)
{
string s1;
s1 = s[i];
dp[i+1] = dp[i]+1;
for (int j = i-1;j >= 0;j --)
{
s1 += s[j];
string s2(s1.rbegin(),s1.rend());
if (s1 == s2) dp[i+1] = min(dp[i+1],dp[j]+1);
}
}
// for (int i = 1;i <= s.size();i ++)
// cout<<i<<' '<<dp[i]<<endl;
cout<<dp[s.size()]-1<<'\n';
}
return 0;
}
B
二分时间,check一下就行了,注意,批改一份试卷至少也要大于等于这份试卷所需时间
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[1010];
int n,k;
int check(ll x)
{
int cnt = 0;
ll sum = 0;
for (int i = 0;i < n;i ++)
{
if (a[i] > x) return 0;
sum += a[i];
if (sum > x)
{
sum = a[i];
++ cnt;
}
}
++ cnt;
return cnt <= k;
}
int main()
{
scanf("%d%d",&n,&k);
ll l = 0,r = 0,mid,ans;
for (int i = 0;i < n;i ++)
{
scanf("%lld",&a[i]);
r += a[i];
l = max(l,a[i]);
}
while (l <= r)
{
mid = (l + r) >> 1;
if (check(mid)) r = mid - 1,ans = mid;
else l = mid + 1;
}
printf("%lld\n",ans);
return 0;
}
C
签到
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
int n,m;
string s;
char c,x;
int flag = 1;
while (~scanf("%c",&c))
{
if (c >= 'a' && c <= 'z') c -= 32;
if (c == ' ') flag = 1;
if (flag && isalpha(c)) putchar(c),flag = 0;
if (c == '\n') putchar('\n'),flag = 1;
}
return 0;
}
D
记错公式+3,cin莫名TLE+2,wa的一声就哭了出来
费马小定理,p为质数,那么
a
p
−
1
≡
1
%
p
a^{p-1} \equiv 1 \% p
ap−1≡1%p
所以,只需输出(a+b)% p即可,然后还要注意会爆long long,所以用一下unsigned long long
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
int n,m;
int t;
unsigned ll p,a,b;
scanf("%d",&t);
while (t --)
{
scanf("%llu %llu %llu",&a,&b,&p);
printf("%llu\n",(a+b)%p);
}
return 0;
}
E
考虑计算出每个点t秒后的位置,从后往前遍历,如果遇到一个位置比后一个更远的,那么他们一定会合并,遇到更小的,肯定不会合并
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> pii;
ll a[100100],x;
int main()
{
int n,t,ans = 0;
scanf("%d %d",&n,&t);
for (int i = 1;i <= n;i ++)
{
scanf("%lld %lld",&a[i],&x);
a[i] += x * t;
}
ll now = (1LL*1<<63)-1;
for (int i = n;i;i--)
{
if (a[i] < now)
{
++ ans;
now = a[i];
}
}
printf("%d\n",ans);
return 0;
}
F
思维,考虑前缀和模p,如果是相同的余数,那么他们的区间和一定就是k的倍数,mp记录一下就行了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 10;
int main()
{
ios::sync_with_stdio(false);
ll n,k,sum = 0;
ll x,ans = 0;
cin>>n>>k;
map<ll,ll> mp;
mp[0] = 0;
for (int i = 1;i <= n;i ++)
{
cin>>x;
sum = (sum + x) % k;
if (!mp.count(sum)) mp[sum] = i;
else ans = max(ans,i - mp[sum]);
}
cout<<ans<<'\n';
return 0;
}
G
签到,暴力搞就行了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> pii;
int a[1010];
int main()
{
ios::sync_with_stdio(false);
ll m,a,c,x,n,g,now;
cin>>m>>a>>c>>x>>n>>g;
for (int i = 0;i < n;i ++)
{
now = (a * x % m + c) % m;
x = now;
}
cout<<x % g<<'\n';
return 0;
}
H
签到,map记录一下就行了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> pii;
int x[500],y[500];
int main()
{
ios::sync_with_stdio(false);
int n,m,ans = 0;
cin>>n;
map<pii,int> mp;
for (int i = 0;i < n;i ++)
{
cin>>x[i]>>y[i];
for (int j = i - 1;j >= 0;j --)
{
int a = x[i] - x[j],b = y[i] -y[j],c = __gcd(a,b);
a /= c,b /= c;
if (!mp[{a,b}] && !mp[{-a,-b}])
{
mp[{a,b}] = 1;
ans ++;
}
}
}
cout<<ans<<'\n';
return 0;
}
I
签到
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int> pii;
int main()
{
//ios::sync_with_stdio(false);
int n,m;
scanf("%d",&n);
if (n % 8 == 0)
printf("%d %d %d\n",n / 8 * 3,n / 8,n * n * 3 / 64);
else printf("%.3lf %.3lf %.3lf\n",n/8.0*3.0,n/8.0,n*n*3.0/64.0);
return 0;
}