好长时间没有写过题解了,以后还是坚持写吧!!!
A
题意:给一个2*n的矩阵,起点是(1, 1),终点是(2, n),矩阵中的数是由0和1组成的move from cell (x1,y1) to cell (x2,y2) in one step if |x1−x2|≤1 and |y1−y2|≤1
,可以左右、上下也可以斜着走,1表示不可以通过,0表示可以过,问可不可以到达终点。
思路:找上下两个数如果都是1的话,就表示不能通过。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int t, n;
int main()
{
cin >> t;
while (t -- ){
cin >> n;
string a1, a2;
cin >> a1 >> a2;
int flag = 0;
for (int i = 0; i < n; i ++ ) {
if (a1[i] == a2[i] && a1[i] == '1') {
cout << "NO" << endl;
flag = 1;
break;
}
}
if (flag == 0) cout <<"YES" << endl ;
}
return 0;
}
B
题意:有
n
n
n个人(偶数),这
n
n
n个人要分成两组,每组的人数一样多是
n
/
2
n/2
n/2,每周每组必须上一节课,而且两组上课不是同一天,给出每个人每天是否空闲,看是否可以分出来两组。
思路:暴力思路,看每个天是否大于等于
n
/
2
n/2
n/2个人,然后看可不可以分成两组。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int t, n, a[N][10], st[N], backup[N];
int main()
{
cin >> t;
while (t -- ) {
cin >> n;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= 5; j ++ )
cin >> a[i][j] ;
vector<int>s[7];
for (int j = 1; j <= 5; j ++ ) {
for (int i = 1; i <= n; i ++ ) {
if (a[i][j] == 1) s[j].push_back(i);
}
}
int flag = 0;
//for (int i = 1; i <= 5; i ++ ) cout << s[i].size() << " ";
//cout << endl;
for (int k = 1; k <= 5; k ++ ) {
for (int i = 1; i <= n; i ++ ) st[i] = 0;
if (s[k].size() >= n / 2) {
for (int i = 0; i < s[k].size(); i ++ ) st[s[k][i]] = 1;
for (int j = k + 1; j <= 5; j ++ ) {
if (s[j].size() >= n / 2) {
int u = 0;
memcpy(backup, st, sizeof st);
for (int x = 0; x < s[j].size(); x ++ ) st[s[j][x]] = 1;
for (int x = 1; x <= n; x ++ ) {
if (st[x] == 0) {
u = 1;
break;
}
}
if (u == 0) {
cout << "YES" << endl;
flag = 1;
break;
}
memcpy(st, backup, sizeof st);
}
}
}
if (flag == 1) break;
}
if (flag == 0) cout << "NO" << endl;
}
return 0;
}
C
题意:给一个长度为n的数组,平均值为k(k为实数),在这个数组里面去2个数,剩下的平均值还是k,问有多少对这样的数。
思路:暴力枚举二分
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+ 10;
long long t, n, sum;
int a[N], b[N];
int main()
{
cin >> t;
while (t -- ) {
cin >> n;
sum = 0;
for (int i = 1; i <= n; i ++ ) {
cin >> a[i];
sum += a[i];
}
for (int i = 1; i <= n; i ++ ) b[i] = 0;
b[n] = 1;
sort(a + 1, a + n + 1) ;
for (int i = n - 1; i >= 1; i -- ) {
if (a[i] != a[i + 1]) {
b[i] = 1;
}
else b[i] = b[i + 1] + 1;
}
//for (int i = 1; i <= n; i ++ ) cout << b[i] << " " ;
//cout << endl ;
int k = floor((double)sum * (double)2 / (double)n);
long long num = 0 ;
if (k != (double)sum * (double)2 / (double)n ) {
cout << 0 << endl;
continue;
}
for (int i = 1; i <= n; i ++ ) {
int d = lower_bound(a + i + 1, a + n + 1, (long long)k - a[i]) - a;
//t
//while (a[i] + a[d] == k && d <= n) d ++;
//cout << i << " " << d << " " << b[d] << endl;
if (d != i && d <= n && a[d] + a[i] == k)num += b[d];
}
cout << num << endl ;
}
return 0;
}
D
题意:从n道题中选择3道题,每道题都有一个主题和一个难度,最少满足两个条件的其中一个,求所有的组合数。
思路:所有的组合去除不满足要求的组合。
代码:
#include <bits/stdc++.h>
using namespace std ;
const int N = 2e5 + 10 ;
int a[N][5] ;
int T, n ;
int st1[N], st2[N] ;
int main()
{
cin >> T ;
while (T -- ) {
cin >> n ;
for (int i = 1; i <= n; i ++ )
st1[i] = 0, st2[i] = 0 ;
for (int i = 1 ; i <= n; i ++ ) {
cin >> a[i][1] >> a[i][2];
st1[a[i][1]] ++ ;
st2[a[i][2]] ++ ;
}
//所有的组合 C(n, 3)
long long ans = (long long) n * (n - 1) * (n - 2) / 6 ;
//不满足要求的组合
for (int i = 1; i <= n; i ++ )
ans -= (long long) (st1[a[i][1]] - 1) * (st2[a[i][2]] - 1) ;
cout << ans << endl ;
}
return 0 ;
}