A. Candies and Two Sisters
题意:两个人分n个东西,a>b,有几种分法
分析:(n-1)/2种
Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define lowbit(x) (x & -x)
#define lrt nl, nr, rt << 1
#define rrt nl, nr, rt << 1 | 1
const ll Inf = 1e18;
const int inf = 0x3f3f3f3f;
template<typename T>
inline void read(T& t)
{
t = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch)) { t = t * 10 + ch - '0'; ch = getchar(); }
t *= f;
}
int main(void)
{
int t;
read(t);
while (t--) {
int n;
read(n);
printf("%d\n", (n - 1) / 2);
}
return 0;
}
B. Construct the String
题意:构造一个长为n的字符串,使得任取一个长为a的子串,有且仅有b种字符
分析:构造一个长度为b的循环串即可
Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define lowbit(x) (x & -x)
#define lrt nl, nr, rt << 1
#define rrt nl, nr, rt << 1 | 1
const ll Inf = 1e18;
const int inf = 0x3f3f3f3f;
template<typename T>
inline void read(T& t)
{
t = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch)) { t = t * 10 + ch - '0'; ch = getchar(); }
t *= f;
}
int main(void)
{
int t;
read(t);
while (t--) {
int n, a, b;
read(n); read(a); read(b);
for (int i = 0; i < n; i++) printf("%c", 'a' + i % b);
printf("\n");
}
return 0;
}
C. Two Teams Composing
题意:n个人有不同的技能点,分成两队,a队中每个人的技能都不同,b队所有人的技能都一样
分析:set存不同的技能数,map存拥有某种技能的人数,直接分的话,有一个人会被分到两队中,分别减去求最大值
Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define lowbit(x) (x & -x)
#define lrt nl, nr, rt << 1
#define rrt nl, nr, rt << 1 | 1
const ll Inf = 1e18;
const int inf = 0x3f3f3f3f;
template<typename T>
inline void read(T& t)
{
t = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch)) { t = t * 10 + ch - '0'; ch = getchar(); }
t *= f;
}
set<int> st;
map<int, int> mp;
int main(void)
{
int t;
read(t);
while (t--) {
st.clear();
mp.clear();
int n;
read(n);
for (int i = 1; i <= n; i++) {
int x;
read(x);
st.insert(x);
mp[x]++;
}
int s1 = st.size();
int s2 = 0;
map<int, int>::iterator it;
for (it = mp.begin(); it != mp.end(); it++) s2 = max(s2, it->second);
int ans = max(min(s1 - 1, s2), min(s1, s2 - 1));
printf("%d\n", ans);
}
return 0;
}
D. Anti-Sudoku
题意:给出一个数独,将其转变为反数独(每行、列、宫有两个相同的)
分析:把任意一个数字改成其他的即可
Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define lowbit(x) (x & -x)
#define lrt nl, nr, rt << 1
#define rrt nl, nr, rt << 1 | 1
const ll Inf = 1e18;
const int inf = 0x3f3f3f3f;
template<typename T>
inline void read(T& t)
{
t = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch)) { t = t * 10 + ch - '0'; ch = getchar(); }
t *= f;
}
char ch[10][10];
int main(void)
{
int t;
read(t);
while (t--) {
for (int i = 1; i <= 9; i++) scanf("%s", ch[i] + 1);
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
if (ch[i][j] == '1') printf("2");
else printf("%c", ch[i][j]);
}
printf("\n");
}
}
return 0;
}
E1. Three Blocks Palindrome (easy version)
题意:给定一个数组,从中取出一部分,都成aba这样的形式,问可以生成的最长目标数组
分析:存下每个数字的位置,因为数据范围小,可以直接枚举a和b的部分
Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define lowbit(x) (x & -x)
#define lrt nl, nr, rt << 1
#define rrt nl, nr, rt << 1 | 1
const ll Inf = 1e18;
const int inf = 0x3f3f3f3f;
const int maxn = 2e3 + 5;
template<typename T>
inline void read(T& t)
{
t = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch)) { t = t * 10 + ch - '0'; ch = getchar(); }
t *= f;
}
int an[maxn];
vector<int> p[30];
int main(void)
{
int t;
read(t);
while (t--) {
for (int i = 1; i <= 26; i++) p[i].clear() ;
int n;
read(n);
for (register int i = 1; i <= n; ++i) {
read(an[i]);
p[an[i]].push_back(i);
}
int ans = 0;
for (register int i = 1; i <= 26; ++i) {
int cnt = p[i].size();
ans = max(ans, cnt); //一种数字作为答案
if (cnt <= 1) continue;
int cnt1 = cnt / 2; //该数字放在两边的最大数量
for (register int j = cnt1; j > 0; --j) {
int num[30] = { 0 };
int maxx = 0;
for (register int k = p[i][j - 1] + 1; k < p[i][cnt - j]; ++k) num[an[k]]++;
for (register int i = 1; i <= 26; ++i) maxx = max(maxx, num[i]);
ans = max(ans, maxx + 2 * j);
}
}
printf("%d\n", ans);
}
return 0;
}
E2. Three Blocks Palindrome (hard version)
题意:和E1一样,只是数据范围加大
分析:直接用E1的代码会tle,因为遍历b部分求众数时,中间部分重复遍历了,我们可以将其分成左右两个部分分别遍历,保证每个数只遍历了一遍
Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a));
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define lowbit(x) (x & -x)
#define lrt nl, nr, rt << 1
#define rrt nl, nr, rt << 1 | 1
const ll Inf = 1e18;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 5;
template<typename T>
inline void read(T& t)
{
t = 0;
int f = 1;
char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch)) { t = t * 10 + ch - '0'; ch = getchar(); }
t *= f;
}
int an[maxn];
vector<int> p[210];
int main(void)
{
int t;
read(t);
while (t--) {
for (int i = 1; i <= 200; ++i) p[i].clear();
int n;
read(n);
for (register int i = 1; i <= n; ++i) {
read(an[i]);
p[an[i]].push_back(i);
}
int ans = 0;
for (register int i = 1; i <= 200; ++i) {
int cnt = p[i].size();
ans = max(ans, cnt); //一种数字作为答案
if (cnt <= 1) continue;
int cnt1 = cnt / 2; //该数字放在两边的最大数量
int num[210] = { 0 };
int maxx = 0;
for (int k = p[i][cnt1 - 1] + 1; k < p[i][cnt - cnt1]; ++k) num[an[k]]++;
for (int i = 1; i <= 200; ++i) maxx = max(maxx, num[i]);
ans = max(ans, maxx + 2 * cnt1);
for (register int j = cnt1 - 1; j > 0; --j) {
for (register int k = p[i][j - 1] + 1; k < p[i][j]; ++k) num[an[k]]++;
for (register int k = p[i][cnt - j - 1]; k < p[i][cnt - j]; ++k) num[an[k]]++;
for (register int i = 1; i <= 200; ++i) maxx = max(maxx, num[i]);
ans = max(ans, maxx + 2 * j);
}
}
printf("%d\n", ans);
}
return 0;
}
F咕咕咕。。。