A
题意: 找到数据中与其他元素不同的元素 – 暴力
AC代码
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define ull unsigned long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define per(i, l, r) for (int i = l; i >= r; --i)
#define mset(s, _) memset(s, _, sizeof(s))
#define mcpy(s, _) memcpy(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define vi vector<int>
#define vpii vector<pii>
#define mp(a, b) make_pair(a, b)
#define debug system("pause")
#define pll pair <ll, ll>
#define fir first
#define sec second
#define inf 0x3f3f3f3f
#define pline cout << endl << endl
inline int lowbit(int x) {return x & -x;}
template< typename T > inline void get_min(T &x, T y) {if(y < x) x = y;}
template< typename T > inline void get_max(T &x, T y) {if(x < y) x = y;}
inline int read() {
int x = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
return f ? -x : x;
}
template<typename T> inline void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
template<typename T> inline void print(T x, char let) {
print(x), putchar(let);
}
const int N = 1e5 + 10;
int t, n, m;
int a[N];
int cnt[N];
int main() {
cin >> t;
while(t -- ) {
cin >> n;
mset(cnt, 0);
rep(i, 1, n) {
cin >> a[i]; cnt[a[i]] ++ ;
}
rep(i, 1, n) {
if(cnt[a[i]] == 1) {
cout << i << endl;
break;
}
}
}
return 0;
}
B
题意:超出棋盘合适的两点与给定两点形成矩形
解法:注意特判给定两点在同一条线与在矩形边界位置即可
AC代码
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define ull unsigned long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define per(i, l, r) for (int i = l; i >= r; --i)
#define mset(s, _) memset(s, _, sizeof(s))
#define mcpy(s, _) memcpy(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define vi vector<int>
#define vpii vector<pii>
#define mp(a, b) make_pair(a, b)
#define debug system("pause")
#define pll pair <ll, ll>
#define fir first
#define sec second
#define inf 0x3f3f3f3f
#define pline cout << endl << endl
inline int lowbit(int x) {return x & -x;}
template< typename T > inline void get_min(T &x, T y) {if(y < x) x = y;}
template< typename T > inline void get_max(T &x, T y) {if(x < y) x = y;}
inline int read() {
int x = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
return f ? -x : x;
}
template<typename T> inline void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
template<typename T> inline void print(T x, char let) {
print(x), putchar(let);
}
const int N = 400 + 10;
int t, n, m;
char a[N][N];
int main() {
cin >> t;
while(t -- ) {
cin >> n;
vpii cor;
rep(i, 1, n) {
rep(j, 1, n) {
cin >> a[i][j];
if(a[i][j] == '*') cor.pb({i, j});
}
getchar();
}
int x1 = cor[0].fir, y1 = cor[0].sec;
int x2 = cor[1].fir, y2 = cor[1].sec;
if(x1 != x2 && y1 != y2) a[x1][y2] = '*', a[x2][y1] = '*';
else {
if(x1 == x2) {
if(x1 != 1 && x1 != n) {
a[x1 + 1][y2] = '*', a[x2 + 1][y1] = '*';
}
else if(x1 == 1) {
a[2][y1] = '*', a[2][y2] = '*';
} else if(x1 == n) {
a[1][y1] = '*', a[1][y2] = '*';
}
} else {
if(y1 != 1 && y1 != n) {
a[x1][y2 + 1] = '*', a[x2][y1 + 1] = '*';
} else if(y1 == 1) {
a[x1][n] = '*', a[x2][n] = '*';
} else if(y1 == n) {
a[x1][1] = '*', a[x2][1] = '*';
}
}
}
rep(i, 1, n) {
rep(j, 1, n) {
cout << a[i][j];
}
cout << endl;
}
}
return 0;
}
C:题意:讲给定串str(01?组成)的’?’全部转换成0或1,使得结果为回文串并且0, 1数量等于a, b – 构造/模拟
解法:
主要是情况要考虑全
1.对于不合法的情况:
a.若str长度为偶数,a或b为奇数
b.str中无’?’,str不回文
c.0,1数量不符合要求
答案的构造方式:
1.对于所有左右有一半为’?’一半为数字的情况,保证回文即可,若出现a, b数量不够,则不合法
2.对于左右都是’?’的情况,只要a, b此时还 > 2即可一一讲成对的?变成1或0
3.此时a, b过剩,遍历一遍目前的str,如果没有?则成功转换,如果存在1个?通过观察a, b的大小补全0或1
若存在多个?说明不合法【注】:这个不合法情况当时没考虑到debug了半天,模拟构造全靠出题人样例QwQ
AC代码
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define ull unsigned long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define per(i, l, r) for (int i = l; i >= r; --i)
#define mset(s, _) memset(s, _, sizeof(s))
#define mcpy(s, _) memcpy(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define vi vector<int>
#define vpii vector<pii>
#define mp(a, b) make_pair(a, b)
#define debug system("pause")
#define pll pair <ll, ll>
#define fir first
#define sec second
#define inf 0x3f3f3f3f
#define pline cout << endl << endl
inline int lowbit(int x) {return x & -x;}
template< typename T > inline void get_min(T &x, T y) {if(y < x) x = y;}
template< typename T > inline void get_max(T &x, T y) {if(x < y) x = y;}
inline int read() {
int x = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
return f ? -x : x;
}
template<typename T> inline void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
template<typename T> inline void print(T x, char let) {
print(x), putchar(let);
}
const int N = 2e5 + 10;
int t, a, b;
string str;
/*
1
2 1
?0?
000
1
4 3
??010?0
0101010
*/
int main() {
cin >> t;
while(t -- ) {
cin >> a >> b;
cin >> str; int siz = str.size();
int num1 = 0, num0 = 0, numc = 0;
rep(i, 0, siz - 1) {
if(str[i] == '1') num1 ++ ;
else if(str[i] == '0') num0 ++ ;
else numc ++ ;
}
if(siz % 2 == 0 && (a & 1 || b & 1)) {
puts("-1");
continue;
}
string tmp(str); reverse(tmp.begin(), tmp.end());
if(numc == 0 && str != tmp) {
puts("-1");
continue;
}
if(numc == 0 && (a != num0 || b != num1)) {
puts("-1");
continue;
}
if(num0 > a || num1 > b) {
puts("-1");
continue;
}
bool fg = 1;
rep(i, 0, siz - 1) {
if(str[i] != '?' && str[siz - 1 - i] != '?') {
if(str[i] != str[siz - 1 - i]) {
fg = 0; break;
}
}
}
if(!fg) {
puts("-1");
continue;
}
a -= num0; b -= num1;
fg = 1;
rep(i, 0, siz - 1) {
if(str[i] != '?' && str[siz - 1 - i] == '?') {
if(str[i] == '1') {
if(b == 0) {
fg = 0; b = 0; break;
}
str[siz - 1 - i] = '1'; b -- ;
} else {
if(a == 0) {
fg = 0; a = 0; break;
}
str[siz - 1 - i] = '0'; a -- ;
}
}
}
if(!fg) {
puts("-1");
continue;
}
if(!a && !b) {
cout << str << endl;
continue;
}
rep(i, 0, siz - 1) {
if(str[i] == '?' && str[siz - 1 - i] == '?') {
if(a > 0 && a - 2 >= 0) {
str[i] = '0'; str[siz - 1 - i] = '0'; a -= 2;
}
else if(b > 0 && b - 2 >= 0) {
str[i] = '1'; str[siz - 1 - i] = '1'; b -= 2;
}
}
}
numc = 0;
rep(i, 0, siz - 1) {
if(str[i] == '?') numc ++ ;
}
if(numc > 1) {
puts("-1"); continue;
}
if(a) {
rep(i, 0, siz - 1) {
if(str[i] == '?') str[i] = '0';
}
} else if(b){
rep(i, 0, siz - 1) {
if(str[i] == '?') str[i] = '1';
}
}
cout << str << endl;
}
return 0;
}
D:题意:给定数组b,b中n + 2个元素有中n个元素来自a(打乱了原序), 有一个元素是a的所有元素之和,一个元素是随机数x,求:a数组中所有的元素
解法:由题目给的数据可知b中所有元素都是正数,故b中表示a的元素和的数s一定是最大的数或者次大的数
故我们只需要枚举两种情况即可
1.如果s是最大的数,枚举剩余的数个是x,剩下的便是a的元素,验证剩下元素之和是否等于s即可
2.若情况1不存在,则s为次大数,a的元素一定是除了最大数的所有数(某一元素不可能大于元素和),也是验证一下即可
AC代码
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define ull unsigned long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define per(i, l, r) for (int i = l; i >= r; --i)
#define mset(s, _) memset(s, _, sizeof(s))
#define mcpy(s, _) memcpy(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define vi vector<int>
#define vpii vector<pii>
#define mp(a, b) make_pair(a, b)
#define debug system("pause")
#define pll pair <ll, ll>
#define fir first
#define sec second
#define inf 0x3f3f3f3f
#define pline cout << endl << endl
inline int lowbit(int x) {return x & -x;}
template< typename T > inline void get_min(T &x, T y) {if(y < x) x = y;}
template< typename T > inline void get_max(T &x, T y) {if(x < y) x = y;}
inline int read() {
int x = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
return f ? -x : x;
}
template<typename T> inline void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
template<typename T> inline void print(T x, char let) {
print(x), putchar(let);
}
const int N = 2e5 + 10;
int t, n;
int b[N];
ll sum[N];
int main() {
cin >> t;
while(t -- ) {
cin >> n; n += 2;
mset(sum, 0);
rep(i, 1, n) cin >> b[i];
sort(b + 1, b + 1 + n);
int maxn1 = b[n], maxn2 = b[n - 1];
rep(i, 1, n) sum[i] = sum[i - 1] + b[i];
int fg = 0, idx = -1;
rep(i, 1, n - 1) {
if(maxn1 == sum[i - 1] - sum[0] + sum[n - 1] - sum[i]) {
fg = 1; idx = i; break;
}
}
if(fg) {
vi ans;
rep(i, 1, n - 1) {
if(i != idx) {
ans.pb(b[i]);
}
else continue;
}
for(auto i : ans) cout << i << ' ';
cout << endl;
continue;
}
if(maxn2 == sum[n - 2]) {
rep(i, 1, n - 2) cout << b[i] << ' ';
cout << endl;
} else {
puts("-1");
}
}
return 0;
}
E
题意:给出1~n的一种排列,使得在区间l~r的数之和等于s,不存在这种排列输出-1 –思维/构造
解法:
我们可以先考虑不合法的情况,按区间的长度分类,例如区间长度len = 3, n = 6的情况下,区间内的最小值即为1, 2, 3
最大值为4, 5, 6, 在1 + 2 + 3 ~ 4 + 5 + 6的所有数都可以在该区间被表出,故只需判断s是否在范围内即可排除非法情况
答案的构造:可以先构造出l~r之间的数保证和等于s,不妨先讲数据设置为最小1, 2, 3, 4, 5....
然后对比s慢慢逼近,构造出s后用剩余的数补全其他空位即可
AC代码
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define ull unsigned long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define per(i, l, r) for (int i = l; i >= r; --i)
#define mset(s, _) memset(s, _, sizeof(s))
#define mcpy(s, _) memcpy(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define vi vector<int>
#define vpii vector<pii>
#define mp(a, b) make_pair(a, b)
#define debug system("pause")
#define pll pair <ll, ll>
#define fir first
#define sec second
#define inf 0x3f3f3f3f
#define pline cout << endl << endl
inline int lowbit(int x) {return x & -x;}
template< typename T > inline void get_min(T &x, T y) {if(y < x) x = y;}
template< typename T > inline void get_max(T &x, T y) {if(x < y) x = y;}
inline int read() {
int x = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
return f ? -x : x;
}
template<typename T> inline void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
template<typename T> inline void print(T x, char let) {
print(x), putchar(let);
}
const int N = 500 + 10;
int t, n, l, r, s;
int ans[N], st[N];
int main() {
cin >> t;
while(t -- ) {
cin >> n >> l >> r >> s;
mset(st, 0);
int len = r - l + 1;
int minv = 0; rep(i, 1, len) minv += i;
int maxn = 0; per(i, n, n - len + 1) maxn += i;
if(s < minv || s > maxn) {
puts("-1"); continue;
}
int cnt = 1, sum = minv;
for(int i = l; i <= r; i ++ ) {
ans[i] = cnt; st[cnt] = 1; cnt ++ ;
}
int idx = r;
while(sum < s) {
if(idx < l) idx = r;
st[ans[idx]] = 0; ans[idx] ++ ; st[ans[idx]] = 1; idx -- ; sum ++ ;
}
for(int i = 1, j = 1; i <= n && j <= n; i ++ ) {
if(i < l || i > r) {
while(st[j] && j <= n) j ++ ;
ans[i] = j; st[j] = 1;
}
}
rep(i, 1, n) cout << ans[i] << ' ';
cout << endl;
}
return 0;
}