1.碰撞2
思路:
只要一条线上方向向右的最左边的人的x坐标大于方向向左的最右边人的坐标就不会撞上,根据这个依据判断即可
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
map<int,pair<int,int>>jilu;
vector<pair<int, int>>shujv;
signed main() {
int n;
cin >> n;
int n1 = n;
while (n1--) {
int a, b;
cin >> a >> b;
shujv.push_back(make_pair(a, b));
}
string c;
cin >> c;
for (int e = 0; e < n; e++) {
int a, b;
a = shujv[e].first;
b = shujv[e].second;
if (c[e] == 'L') {
if (jilu[b].first < a) {
jilu[b].first = a;
}
}
else {
if (a == 0) {
jilu[b].second = -1;
}
if (jilu[b].second == 0) {
jilu[b].second = a;
}
if (jilu[b].second > a) {
jilu[b].second = a;
}
}
int bijiao1 = jilu[b].first, bijiao2 = jilu[b].second;
//cout << bijiao1 << " " << bijiao2 << endl;
if (bijiao1 == 0 || bijiao2 == 0) {
}
else {
if (bijiao1 >= bijiao2) {
cout << "Yes";
return 0;
}
}
}
cout << "No";
return 0;
}
2.优美!最长上升子序列
思路:
动态规划扫一遍,主要问题是超时,需要控制外循环为从小到大每个数,内循环为外循环数的倍数,其他要求按题目的要求判断即可
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
int n;
cin >> n;
int n1 = n;
while (n1--) {
int a1;
cin >>a1;
vector<int>shujv(a1 + 1), pd(a1 + 1, 1);
for (int e = 1; e <= a1; e++) {
scanf("%d", &shujv[e]);
}
int mx = 1;
pd[1] = 1;
for (int e = 1; e <=a1; e++) {
for (int j = e * 2; j <= a1; j += e)
{
if (shujv[j] > shujv[e])pd[j] = max(pd[j], pd[e] + 1);
mx = max(mx,pd[j]);
}
}
printf("%d\n", mx);
}
}
3.巨大的牛棚
思路:
暴力算会超时,所以预处理一下数据,如果没有数就把二维数组中对应的数据存为0,有树就存为1;然后建立一个二维数组,每个位置表示从1,1点一直到该位置的一个行列式的和,然后用二分法处理长度,最后输出左值
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
int q, n;
int ycl[1005][1005];
int zhi[1005][1005];
int check(int mid) {
for (int e = mid; e <= q; e++) {
for (int i = mid; i <= q; i++) {
if (ycl[e][i] - ycl[e - mid][i] - ycl[e][i - mid] + ycl[e - mid][i - mid] == 0) {
return 1;
}
}
}
return 0;
}
signed main() {
cin >> q >> n;
int n1 = n;
vector<vector<int>>tu;
while (n1--) {
int a, b;
cin >> a >> b;
zhi[a][b] = 1;
}
for (int e = 1; e <= q; e++) {
for (int i = 1; i <= q; i++) {
ycl[e][i] = ycl[e - 1][i] + ycl[e][i - 1] - ycl[e - 1][i - 1] + zhi[e][i];
}
}
int l = 1,r=q;
while (l +1< r) {
int mid = (l + r) / 2;
if (check(mid)) {
l = mid;
}
else {
r = mid;
}
}
cout << l;
return 0;
}
4.高利贷
思路:
套公式,二分法,注意cout的输出小数可能不全
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
double a, b, c;
int check(double mid) {
double lv = 1 / (1 + mid);
double a1 = b / (1 + mid);
double shang = a1 * (1 - pow(lv, c));
double xia = 1 - lv;
double jie = shang / xia;
if (jie > a) {
return 1;
}
return 0;
}
signed main() {
cin >> a >> b >> c;
double l = 0, r = 10;
while (r - l >=1e-9) {
double mid = l + r;
mid /= 2;
if (check(mid)) {
l = mid;
}
else {
r = mid;
}
}
printf("%.8lf", l);
}
5.背包
思路:
本来以为是背包问题,没想到是逻辑问题,如果遇到大于w/2小于w直接判YES,遇到大于W的不用管,遇到小于w/2的加到和上,如果he>w/2,则YES,否则NO
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
int asdf;
cin >> asdf;
while (asdf--) {
int n,w;
cin >> n>>w;
int n1 = n;
vector<int>shujv;
while (n1--) {
int b;
cin >> b;
shujv.push_back(b);
}
int he=0;
int panduan = 1;
for (int e = 0; e < n; e++) {
if (shujv[e]*2 >w) {
if (shujv[e] <= w) {
panduan = 0;
cout << "YES" << endl;
break;
}
}
else {
if (he + shujv[e] <= w) {
he += shujv[e];
}
if (he*2 >= w) {
panduan = 0;
cout << "YES" << endl;
break;
}
}
}
if (panduan) {
cout << "NO" << endl;
}
}
}
6.三回文序列
思路:
先遍历一遍数组,记录每个元素的出现次数,然后枚举所有的数作为a(三回文是一种aba形式的字符串),每次枚举把两边的a的个数都算出来,再枚举中间的b的个数,取总和最大值
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
int n;
int change(vector<int>v, int ans, vector<int>nums)
{
int l = 0, r = n - 1, cnt = 0, res = nums[ans];
while (l < r)
{
while (l < r && v[l] != ans)
{
nums[v[l]]--;
l++;
}
while (l < r && v[r] != ans)
{
nums[v[r]]--;
r--;
}
cnt += min(nums[ans], 2);
nums[ans] -= 2;
l++, r--;
for (int i = 1; i <= 26; i++)res = max(res, cnt + nums[i]);
}
return res;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin >> t;
while (t--)
{
cin >> n;
vector<int>v(n), nums(27);
for (int i = 0; i < n; i++)
{
cin >> v[i];
nums[v[i]]++;
}
int res = 0;
for (int i = 1; i < 27; i++)
{
if (nums[i] != 0)
res = max(res, change(v, i, nums));
}
cout << res << endl;
}
return 0;
}
7.简单的异或问题
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
typedef long long ll;
int main()
{
ll n, m;
cin >> n >> m;
ll res = 1;
res <<= m;
if (m == 1 && n == 0)
{
cout << 1 << endl;
}
else if (m == 1 && n == 1)
{
cout << 2 << endl;
}
else cout << (1LL) * (res - min(n, 1LL)) << endl;
return 0;
}
8.子串的循环挪动
思路:
我们也可以把需要挪动的子串分成两部分,长度为k的s2尾部子串(将要挪去前面的那部分),和将要从前面移动到后面的s2的头部子串,所以我们整体可以把字符串分成三部分:s的头部s1,需要挪动的子串的头部s2,需要挪动的子串的尾部s3,s的尾部s4.
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
string str;
cin >> str;
int m, n = str.size();
cin >> m;
while (m--)
{
int l, r, k;
cin >> l >> r >> k;
int mod = (r - l + 1);
string s1 = str.substr(0, l - 1);
string s2 = str.substr(l - 1, r - l - (k % mod) + 1);
string s3 = str.substr(r - k % mod, k % mod);
string s4 = str.substr(r, n - r + 1);
if (l != r)
str = s1 + s3 + s2 + s4;
}
cout << str << endl;
return 0;
}
9.弗拉德和糖果 II
思路:
我们只用判断最大值与其他值的和的关系即可.
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
const int MOD = 1e9 + 7, N = 1e6 + 10;
inline int read() {
int x = 0; char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x;
}
int main()
{
int n;
long long sum = 0, mx = 0, num;
n = read();
for (int i = 0; i < n; i++)
{
num = read();
if (mx < num)
{
sum += mx;
mx = num;
}
else sum += num;
}
if ((n == 1 && mx == 1) || mx <= sum + 1)
{
puts("YES");
}
else
{
puts("NO");
}
return 0;
}
10.上帝的集合
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<queue>
#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e6 + 10;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
ll t, add = 0;
priority_queue<ll, vector<ll>, greater<ll>>que;
cin >> t;
while (t--)
{
int st;
cin >> st;
if (st == 1)
{
ll x;
cin >> x;
que.push(x - add);
}
else if (st == 2)
{
ll x;
cin >> x;
add += x;
}
else
{
cout << que.top() + add << endl;
que.pop();
}
}
return 0;
}