img

广州大学新生赛

A

算出在x轴和y轴的投影即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
typedef long long int ll;
typedef pair<ll, int> PII;
const int N = 1e5 + 10, M = 2e5 + 10;
double ax, ay;
int main()
{
int n;
cin >> n;
while (n--)
{
ll x, y;
double f;
cin >> x >> y >> f;
if (x == 0 && y == 0)
{
continue;
}
double coa = f * x / sqrt((x * x + y * y));
double coy = f * y / sqrt((x * x + y * y));
ax += coa;
ay += coy;
}
printf("%.3lf %.3lf", ax, ay);
return 0;
}

B

小的就直接加

加完之后直接判断就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
using namespace std;
int main()
{
int a[6];
for (int i = 1; i <= 5; i++)
{
cin>>a[i];
}
int f = 1;
for (int i = 1; i <= 3; i++)
{
if (a[i] != a[i + 1])
{
if (a[i] < a[i + 1])
{
a[i] += a[5];
}
else
{
a[i + 1] += a[5];
}
break;
}
}
for (int i = 1; i <= 3; i++)
{
if (a[i] != a[i + 1])
{
f = 0;
break;
}
}
if (!f)
{
cout << "NO" << endl;
}
else
{
cout << "YES" << endl;
}
}

C

注意最大值一定是两边的最大值(不论正还是负)推出来的,这样就行.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//注意坑就行
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e9 + 7;

void solve()
{
ll n, x1 = -N, y1 = -N, x2 = N, y2 = N, ans;
bool n1 = false, m1 = false;
cin >> n;
while (n--)
{
cin >> ans;
if (ans % 2)
{
n1 = true;
x1 = max(x1, ans);
x2 = min(x2, ans);
}
else
{
m1 = true;
y1 = max(y1, ans);
y2 = min(y2, ans);
}
}
if (n1 && m1)
{
cout << max(max(x1 * y1, x2 * y2), max(x1 * y2, x2 * y1));
}
else
cout << -1;
}

int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
// cin>>t;
while (t--)
solve();
return 0;
}

D

计算出期望,直接计算每一道题目的概率。

这样每一道题目的概率只由它和它前面的题总共两道题推出,因此只需要推导出这个公式进行累加即可。

注意这个公式:有时候会用到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//期望是可加的,我们可以计算出每一道题的概率
//计算方法如下;
//min(a[i],a[i-1])/(a[i]*a[i-1])
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> a(n);
for (auto &ai : a)
cin >> ai;
double ans = 0;
for (int i = 1; i < n; i++)
ans += 1.0 / max(a[i], a[i- 1]);
ans += 1.0 / max(a[n- 1], a[0]);
cout << fixed << setprecision(6) << ans << '\n';
return 0;
}

E

写个表,我们就可以知道

a|b=a&b+a^b

因此就可以换了

那这个数一定是偶数

然后就看下面罢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//严重怀疑软院新生赛某题为此题
//a|b=a&b+a^b
//转换为a|b=c/2
//如果c是奇数,拜拜了
//如果c/2某位是0,a这一位是1,拜拜了
//其余只需要在a是0的情况b是1就行了
//妙哉
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
cin.tie(0), cout.tie(0);
ll a, c;
cin >> a >> c;
if ((c & 1) || (a & (c / 2)) != a)//a为1的位数,c/2也必须要是1
cout << " 1\n";
else
//符合异或,a为1,b就0,a为0,b为1
cout << (a ^ (c / 2)) << '\n';
return 0;
}

F

暴力枚举操作1,每次看看能够放多少个在后面

然后暴力枚举回文数,由于有费用的限制因此需要考虑两种修改回文的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//什么回文机
//什么背包
//暴力枚举操作1
//然后暴力枚举操作2,3
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define mp make pair
#define pii pair<int, int>
int main()
{
int n, a, b, c;
cin >> n >> a >> b >> c;
string s;
cin >> s;
int ans = 2e9;
for (int i = 0; i < n; i++)
{
int res = i * a;
string t = s.substr(i) + s.substr(0, i); // t为执⾏i次操作⼀后的字符串
for (int j = 0; j < n / 2; j++)
{ // 考虑⼀半即可
if (t[j] != t[n- 1-j])
{
if (isupper(t[j]) && isupper(t[n -1 -j]))
{
res += min(2 * c, b);
}
else if (islower(t[j]) && islower(t[n -1- j]))
{
res += min(2 * b, c);
}
else
{
res += min(b, c);
}
}
}
ans = min(ans, res); // 每次操作答案取min
}
cout << ans << "\n";
return 0;
}

G

思考一下,如果只有一个必赢。

如果是偶数,然后最大值在中间,无论是/2还是/2+1都可以

你可以举一个为4的例子去想一下

然后的话如果是奇数

然后如果在中间就输了

其余情况直接就是平局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int a[100010];
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
int j;
int max = 0, idx = 0;
for (int i = 1; i <= n; i++)
{
cin >> j;
if (j > max)
{
max = j;
idx = i;
}
}
//记录最大值的下标
if (n == 1 || n % 2 == 0 && (idx == (n / 2) || idx == ((n / 2) + 1)))
cout << "Win!"
<< "\n";

else if (n % 2 != 0 && idx == ((n) / 2 + 1))
cout << "Lose!"
<< "\n";
else
cout << "Draw!"
<< "\n";
}
return 0;
}

H

都是0或1,然后挑选两个数字

只需要进行统计

然后是0就加上1个个数,然后把0的个数给减去了

同理,1也是。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//如果不是0或1(不会)
//但是这个还是比较简单的
#include <stdio.h>
int n;
int a[200010] = {0};
int main()
{
scanf("%d", &n);
int n1 = 0, n0 = 0;
long long sum = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
if (a[i] == 0)
n0++;
else
n1++;
}
for (int i = 1; i < n; i++)
{
if (a[i] == 0)
{
sum += n1;
n0--;
}
else if (a[i] == 1)
{
sum += n0;
n1--;
}
}
printf("%lld", sum);
return 0;
}

I

递推转移过来就好了

一个是左上角,一个是右上角

然后从下往上进行转移

注意要减去1这一个细节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//动态规划
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, int> PII;
int num[2010][2010];
int cz[2010][2010];
int cy[2010][2010];
int cu[2010][2010];
int n;
int main()
{
cin>>n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin>>num[i][j];
cz[i][j] = num[i][j] == 1 ? cz[i - 1][j - 1] + 1 : 0;
cy[i][j] = num[i][j] == 1 ? cy[i - 1][j + 1] + 1 : 0;
//向左递推
//向右递推
}
}
ll ans = 0;
for (int i = n; i >= 1; i--)
{
for (int j = n; j >= 1; j--)
{
//从下往上递推
cu[i][j] = num[i][j] == 1 ? cu[i + 1][j] + 1 : 0;
if (num[i][j] == 1)
{
ans += min({cu[i][j] - 1, cz[i][j] - 1, cy[i][j] - 1});
}
}
}
cout << ans << endl;
return 0;
}

J

其实就是暴力()以为是某某bfs(在后面)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
typedef long long int ll;
typedef pair<ll, int> PII;
char s[1010][1010];
int n, m;
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
scanf("%s", s[i] + 1);
}
int di, dj;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (s[i][j] == 'W')
{
di = i;
dj = j;
}
}
}
ll ans = 10000;
for (int i = n; i >= 1; i--)
{
for (int j = m; j >= 1; j--)
{
if (s[i][j] == 'O')
{
ans = min(ans, 0LL + abs(i - di) + abs(j - dj));
}
}
}
cout << ans << endl;
return 0;
}

L

由于和位置没有关系

只需要记录0和1的个数

跑bfs

记录一下含义disti j为白为i,黑为j需要走的步数+1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <bits/stdc++.h>
using namespace std;
const int N = 5e3 + 10;
int dist[N][N];
int n, m;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int x = 0, y = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
int a;
cin >> a;
if (a == 0)
x++;
else
y++;
}
dist[x][y] = 1;
typedef pair<int, int> PII;
queue<PII> q;
q.push({x, y});
while (q.size())
{
PII t = q.front();
int d = dist[t.first][t.second];
q.pop();
for (int i = 0; i <= min(t.first, m); i++)
{
if (t.second < m - i)
continue;
//白的多了m-i个,黑的多了i个,于是就有了上面的限制
int a = t.first - i + m - i, b = n - a;

if (dist[a][b] == 0)
{
dist[a][b] = d + 1;
q.push({a, b});
}
}
}
cout << dist[n][0] - 1 << " " << dist[0][n] - 1 << '\n';
return 0;
}

M

采用离散化的方式进行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define frep(i, a, n) for (int i = a; i >= n; i--)
using ll = long long;
using namespace std;
const int N = 2e5 + 100;
int a[N],b[N],c[N],d[N];
int main()
{
int n,q;
cin>>n;
rep(i,1,n)
{
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+1+n);
int m=unique(b+1,b+1+n)-b-1;
rep(i,1,n)
{
a[i]=lower_bound(b+1,b+m+1,a[i])-b;
}
cin>>q;
while(q--)
{
int l,r;
cin>>l>>r;
if(r-l+1>m)
{
cout<<-1<<'\n';
}
else
{
rep(i,l,r)
{
c[a[i]]++;
}
int cnt=0;
rep(i,1,m)
{
while(c[i])
{
d[++cnt]=b[i];
--c[i];
}
}
int ans=d[2]-d[1];
rep(i,2,cnt)
{
if(d[i]-d[i-1]!=ans)
{
ans=-1;
}
}
if(ans==0)
{
ans=-1;
}
cout << ans << '\n';
}

}


return 0;
}
img