A - 腿
分析
贪心 使动物尽可能是牛。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
int t,n;
void solve()
{
cin>>n;
//2 4
if(n<4)
{
cout<<n/2<<endl;
}
else
{
int cnt=n/4;
if(n%4==0)
cout<<cnt<<endl;
else
cout<<cnt+1<<endl;
}
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>t;
while(t--)solve();
return 0;
}
B - 缩小
分析
模拟 每次移动k个单位。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1005;
int t,n,k;
char s[N][N];
bool st[N];
void solve()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>s[i][j];
//每次输出间隔k。那就+=k
for(int i=1;i<=n;i+=k)
{
for(int j=1;j<=n;j+=k)
cout<<s[i][j];
cout<<endl;
}
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>t;
while(t--)solve();
return 0;
}
C - 字符串
分析
这道题有点难崩,一开始数组开小了,第3个点RE,改完后第二个点又t了……
前缀和 要使排序后的两个字符串相同,那就是排序前区间内可能的字符数相同,所以对 a , b 字符串求字符数的前缀和,最终看差这里就做差即可。统计的时候,暴力去枚举每个字母有一个不同那就记录。
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N=2e5+10;
int s[N][30];
int n,q;
string a,b;
void solve()
{
cin>>n>>q>>a>>b;
for(int i=1;i<=n;i++)
{
for(int j=0;j<26;j++)s[i][j]=s[i-1][j];//每个字母的次数都遍历一遍,后=前也是一种前缀和方法
s[i][a[i-1]-'a']++;//统计次数
s[i][b[i-1]-'a']--;
}
while(q--)
{
int l,r;
cin>>l>>r;
l--;
int ans=0;
for(int i=0;i<26;i++)
ans+=max(0,s[r][i]-s[l][i]);
cout<<ans<<endl;
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--)solve();
return 0;
}
D - 答案个数
分析
数学&&暴力这道题,如何枚举不超时是要思考的。最简单的方法是修复 $a$ 、 $b$ 或 $c$ 。我们来修正 $a$ 。由于 $ab + ac + bc \leq n$ ,我们至少知道 $ab \leq n$ 。两边相除,得到 $b \leq \frac{n}{a}$ 。当 $a = 1$ 时, $b$ 有 $n$ 个选择。当 $a = 2$ 时, $b$ 有 $\frac{n}{2}$ 个选择。因此, $b$ 总共有 $n + \frac{n}{2} + \frac{n}{3} + … + \frac{n}{n}$ 个选项。这还只是调和数列,所以在所有可能的 $a$ 中, $b$ 大约有 $n \log n$ 个选择。因此,我们可以同时循环 $a$ 和 $b$ 。
现在我们有了 $a$ 和 $b$ ,剩下的就是求解 $c$ 了。我们来求解这两个等式中的 $c$ 。在第一个等式中,我们可以将 $c$ 因式分解,得到 $ab + c(a+b) \leq n$ 。所以是 $c \leq \frac{n-ab}{a+b}$ 。在第二个等式中, $c \leq x - a - b$ 。由于我们希望 $c$ 同时满足两个不等式,因此必须选择较严格的一个。因此,可能的 $c$ 个数为 $\min(\frac{n-ab}{a+b},x-a-b)$ 。
答案是所有可能的 $a$ 和 $b$ 中可能的 $c$ 个数之和。
//由公式得出限制条件
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=2e5+10;
int n,x;
void solve()
{
cin>>n>>x;
int ans=0;
for(int a=1;a<=n;a++)
{
for(int b=1;a*b<=n&&a+b<=x;b++)
{
ans+=min((n-a*b)/(a+b),x-a-b);
}
}
cout<<ans<<endl;
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--)solve();
return 0;
}
E、F、G还没做