传送门:https://codeforces.com/contest/1996
第一题:Legs
题意:思路:贪心(尽可能选择牛)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
int n;
cin >> n;
cout << n / 4 + ( n % 4 ) / 2 <<endl;
}
int main()
{
int tt; cin >> tt;
while (tt--)solve();
return 0;
}
第二题:Scale
题意:
思路:(模拟题)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 10;
int a[N][N];
int b[N][N];
void solve()
{
memset(a, 0, sizeof a);
memset(b, 0, sizeof b);
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++)
{
string s;
cin >> s; s = " " + s;
for (int j = 1; j <= n; j++) {
a[i][j] = s[j] - '0';
}
}
int row = 0; int col = 0;
for (int i = 1; i <= n; i += k)
{
row++;
for (int j = 1, col = 1; j <= n; j += k, col++)
{
b[row][col] = a[i][j];
}
}
for (int i = 1; i <= row; i++)
{
for (int j = 1; j <= row; j++)cout << b[i][j];
cout << endl;
}
}
int main()
{
int tt; cin >> tt;
while (tt--)solve();
return 0;
}
第三题:Sort
思路:(前缀和 + 模拟)
1. 设 f [i][j] 为前i个字母中 , 字符 j + 'a' 出现的次数
2. 一段区间中,a中字符串中的字符数 - b中字符串中的字符数 -> 替换的次数
eg: 1 a b c d e g g
2 g g b e f f d
1中字符串 'a' 和 'c' 的个数多于 2中的字符串 答案为2
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int f[N];
int ch1[N][27];
int ch2[N][27];
void solve()
{
memset(f, 0, sizeof f);
memset(ch1, 0, sizeof ch1);
memset(ch2, 0, sizeof ch2);
int n, q;
cin >> n >> q;
string s1, s2;
cin >> s1 >> s2;
s1 = " " + s1; s2 = " " + s2;
for (int i = 1; i <= n; i++)
{
ch1[i][s1[i] - 'a' + 1]++; ch2[i][s2[i] - 'a' + 1]++;
for (int j = 1; j <= 26; j++)ch1[i][j] += ch1[i - 1][j], ch2[i][j] += ch2[i - 1][j];
}
while (q--)
{
int l, r;
cin >> l >> r;
int temp1[27] = { 0 };
int temp2[27] = { 0 };
for (int i = 1; i <= 26; i++)temp1[i] = ch1[r][i] - ch1[l - 1][i];
for (int i = 1; i <= 26; i++)temp2[i] = ch2[r][i] - ch2[l - 1][i];
for (int i = 1; i <= 26; i++)temp1[i] -= temp2[i];
int res = 0;
for (int i = 1; i <= 26; i++)if (temp1[i] > 0)res += temp1[i];
cout << res << endl;
}
// cout << endl;
}
int main()
{
int tt; cin >> tt;
while (tt--)solve();
return 0;
}
第四题:Fun
题意:
思路:
通过枚举 a b , 确定 c 的个数 , 从而确定(a,b,c)的个数
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
int n , x;
cin >> n >> x;
int ans = 0;
for( int a = 1; a <= n ; a++)
{
for( int b = 1 ; a + b <= x && a * b <= n ; b++)
{
ans += min((n - a * b ) / ( a + b ) , x - a - b );
}
}
cout << ans << endl;
}
signed main()
{
int tt;
cin >> tt;
while(tt--)solve();
return 0;
}
第五题:Decode
题意:
思路:
1. 如何确定一段区间内 0 1 个数相等 -> 将 0 当做 -1 ,1 当做 1处理,若0 1个数相等,则说明这一段区间和为0 f[r] == f[l-1]
2. 如何确定(l , r)对(x,y)的贡献 -> 扩展(x,y), (x,y) 那么x的范围 * y的范围
就是贡献 x * ( n - y + 1 )
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10;
const int mod = 1e9 + 7;
int pre[N];
void solve()
{
string s;cin>> s;
int n = s.size();
s = " " + s;
for( int i = 1 ;i <= n;i++)
{
pre[i] = pre[i-1] + (s[i] == '1' ? 1 : -1);
}
map<int,int> cnt;
cnt[0] = 1; // 初始化
int ans = 0;
for( int i = 1; i<= n;i++)// 枚举右端点
{
ans = (ans + cnt[pre[i]] * (n - i + 1 )) % mod;
cnt[pre[i]] = (cnt[pre[i]] + i + 1) % mod;
// 为什么要 cnt[pre[i]] + i + 1
// cnt[pre[i]] 因为前面的左边界的选法仍会影响后面 , + 1 是为了保证 pre[r] == pre[l-1] , 此时 i + 1 才是 l 的长度
}
cout << ans <<endl;
}
signed main()
{
int tt;
cin >>tt;
while(tt--)solve();
return 0;
}