(咕咕咕了挺久了,感觉还是要写下)
A. Div. 7 (思维+数学)
可以发现对于任意一个数字,我们最多需要修改一位数。
我们可以假设k=n%7,只需修改个位数字p -> p-k/ p->p-k+7(一定有一个符合)
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
using namespace std;
ll n;
void sol()
{
ll ans=n%7,k=n%10;
if (k-ans>=0)
printf("%lld\n",n-ans);
else
printf("%lld\n",n+7-ans);
}
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
{
scanf("%lld",&n);
sol();
}
return 0;
}
B. Minority(贪心+思维)
我们可以设a为0的个数,b为1的个数
如果a!=b,ans=min(a,b)
如果a=b,我们可以删除首字符或尾字符,ans=a-1=b-1
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
using namespace std;
ll a[Ma];
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
{
string s;
cin>>s;
ll x=0,y=0;
for (ll i=0;i<s.size();i++)
if (s[i]=='1')
x++;
else
y++;
if (x==y)
printf("%lld\n",x-1);
else
printf("%lld\n",min(x,y));
}
return 0;
}
C. Kill the Monster(暴力/数论)
当时看到这题,心想这不是数论裸板子么,写了10分钟一看过了一坨人,再看了下k<=2e5,😭;
方法一:O()枚举回合数(经典数论莫反),显然容易炸
方法二:可以发现升级一定是用满的(毕竟不加白不加),因此枚举情况取最大即可。
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
using namespace std;
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
{
ll hc,dc,hm,dm;
scanf("%lld %lld",&hc,&dc);
scanf("%lld %lld",&hm,&dm);
ll k,w,a;
scanf("%lld%lld%lld",&k,&w,&a);
ll flag=0;
for (ll i=0;i<=k;i++)
{
ll x=(hc+a*i-1)/dm,y=(hm-1)/(dc+w*(k-i));
if (x>=y)
flag=1;
}
if (flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
D. Make Them Equal(打表+dp优化)
首先我们可以用o()打表得出第i个数字需要花费ask[a[i]]次操作,用背包实现O(n*k),显然这会TLE(博主过于傻逼认为CFYYDS,1s1e9不是梦,然后TLE12了)。然后我们发现上面打表后每个数的操作次数最多为12次,因此可以优化到O(12*),这就可以ACrua。
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
using namespace std;
ll dp[Ma];
ll ask[Ma];
ll a[Ma],b[Ma];
ll n,k;
ll ma=0;
void sol()
{
if (n*ma<=k)
{
ll ans=0;
for (ll i=1;i<=n;i++)
ans+=b[i];
printf("%lld\n",ans);
return;
}
for (ll i=1;i<=n;i++)
{
for (ll j=k;j>=ask[a[i]];j--)
dp[j]=max(dp[j],dp[j-ask[a[i]]]+b[i]);
}
printf("%lld\n",dp[k]);
return;
}
int main()
{
memset(ask,0x3f,sizeof(ask));
ask[1]=0;
for (ll i=1;i<=1000;i++)
for (ll j=i;j>=1&&i+i/j<=1000;j--)
ask[i+i/j]=min(ask[i+i/j],ask[i]+1);
for (ll i=1;i<=1000;i++)
ma=max(ma,ask[i]);
cout<<ma<<endl;
ll tt;
scanf("%lld",&tt);
while (tt--)
{
scanf("%lld%lld",&n,&k);
memset(dp,0,sizeof(dp));
for (ll i=1;i<=n;i++)
scanf("%lld",&a[i]);
for (ll i=1;i<=n;i++)
scanf("%lld",&b[i]);
sol();
}
return 0;
}
最近场数比较多,加上开学事也多,而且感觉E我也不是很擅长,就看心情随缘补rua