A
思路:就是三个点如果任意两个点的横坐标相同,并且任意两个点的纵坐标相同的话就不行。
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
const int N = 100;
int a[N];
map<int, int> b;
map<int, int> c;
void solve()
{
int flag1 = 1, flag2 = 1;
for (int i = 1; i <= 6; i++)
cin >> a[i];
for (int i = 1; i <= 6; i += 2)
{
b[a[i]]++;
if (b[a[i]] == 2)
flag1 = 0;
}
for (int i = 2; i <= 6; i += 2)
{
c[a[i]]++;
if (c[a[i]] == 2)
flag2 = 0;
}
if (!flag1 && !flag2)
{
cout << "NO" << endl;
}
else
{
cout << "YES" << endl;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while (T--)
{
b.clear();
c.clear();
solve();
}
return 0;
}
B
思路:按题意模拟一遍即可,但是第二个到第n个要先排序。
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int a[N];
void solve()
{
int n;
cin >> n;
int sum = 0;
int k;
cin >> k;
for (int i = 1; i < n; i++)
{
cin >> a[i];
}
sort(a + 1, a + n);
for (int i = 1; i < n; i++)
{
if (k < a[i])
{
int j = k + a[i];
if ((k + a[i]) % 2 == 0)
{
k = (k + a[i]) / 2;
a[i] = (k + a[i]) / 2;
}
else
{
k = (k + a[i]) / 2 + 1;
a[i] = (k + a[i]) / 2;
}
}
}
cout << k << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
C
C题是比较难的一个题
思路:首先我们考虑
a
[
1
]
[
i
]
,
a
[
2
]
[
i
]
,
a
[
3
]
[
i
]
,
.
.
.
,
a
[
i
]
[
i
]
a[1][i],a[2][i],a[3][i],...,a[i][i]
a[1][i],a[2][i],a[3][i],...,a[i][i]我们可以发现这样它必须是222221111的这种情况(我们先不考虑0的情况)也就是前面是2后面是1的情况。我们定义
f
[
L
]
[
R
]
f[L][R]
f[L][R]是1 ~ L-1是2,并且L ~ R是1的串的方案数。然后我们考虑状态转移。状态转移可以分两种情况如果第R和R+1是相同的那么就是
f
[
L
]
[
R
+
1
]
=
f
[
L
]
[
R
+
1
]
+
f
[
L
]
[
R
]
f[L][R+1] =f[L][R+1]+ f[L][R]
f[L][R+1]=f[L][R+1]+f[L][R],如果是不同的
f
[
R
+
1
]
[
R
+
1
]
=
f
[
R
+
1
]
[
R
+
1
]
+
f
[
L
]
[
R
]
f[R+1][R+1] = f[R+1][R+1]+f[L][R]
f[R+1][R+1]=f[R+1][R+1]+f[L][R],我们在具体实现的时候还要判断一下情况是否成立。借鉴的大佬的思路传送门大佬有图文便于理解。非常建议去康康。
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int N = 1e2 + 10, mod = 998244353;
int a[N][N], dp[N][N];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
cin >> a[i][j];
dp[1][1] = 2;//一开始没要求,可以存1或者0,所以是两种方案。
for (int R = 1; R <= n; R++)
{
for (int L = 1; L <= R; L++)
{
bool flag = true;
for (int i = 1; i <= L - 1; i++)
if (a[i][R] == 1)
flag = false;
for (int i = L; i <= R; i++)
if (a[i][R] == 2)
flag = false;
if (!flag)//方案不合理的话就直接赋成0
dp[L][R] = 0;
(dp[L][R + 1] += dp[L][R]) %= mod;
(dp[R + 1][R + 1] += dp[L][R]) %= mod;
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
(ans += dp[i][n]) % mod;
cout << ans % mod << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
while (T--)
{
solve();
}
return 0;
}
D
思路:佬们直接猜的结论,比赛的时候我并没有猜出来
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int a[N];
void solve()
{
int n;
string s;
int sum1 = 0;
int sum0 = 0;
cin >> n >> s;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '1')
sum1++;
else
sum0++;
}
int left = pow(2, sum1);
int right = pow(2, n) - pow(2, sum0) + 1;
for (int i = left; i <= right; i++)
{
cout << i << ' ';
}
cout << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T=1;
while (T--)
{
solve();
}
return 0;
}