比赛主页:第十届“图灵杯”NEUQ-ACM程序设计竞赛
直接判断是否升序或降序,可以调用STL函数is_sorted()简化写法
#include
#define int long long
#define x first
#define y second
using namespace std;
void solve()
{
int n;
cin >> n;
vector<int> a(n), b(n);
for (int i = 0; i < n; i++) cin >> a[i], b[i] = a[i];
reverse(b.begin(), b.end());
if (is_sorted(a.begin(), a.end()) || is_sorted(b.begin(), b.end()))
cout << "erfen is useful!";
else cout << "bukeyi";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
直接判断即可
#include
#define int long long
#define x first
#define y second
using namespace std;
void solve()
{
string s;
cin >> s;
int a = s[0] - '0';
int b = s[1] - '0';
int c = s[2] - '0';
int d = s[3] - '0';
if (a + b == c + d) cout << "YES" << '\n';
else cout << "NO" << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}
计算在 y = y p y=y_p y=yp 时的 x x x 区间,然后判断 x p x_p xp 是否在区间内即可
#include
#define int long long
#define x first
#define y second
using namespace std;
void solve()
{
double xb, xc, yc;
cin >> xb >> xc >> yc;
int xp, yp;
cin >> xp >> yp;
if (yp >= yc) cout << "no" << '\n';
else
{
// 计算区间,我这里使用相似三角形推的公式
double l = yp * xc / yc;
double r = xb - (yp * (xb - xc) / yc);
if (l < xp && r > xp) cout << "yes" << '\n';
else cout << "no" << '\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
模拟,用 i s t r i n g s t r e a m istringstream istringstream 来依次获取每行的每个单词,然后对单词进行处理
#include
#define int long long
#define x first
#define y second
using namespace std;
void solve()
{
string str;
vector<string> vec;
int ans = 0;
string s1 = "NEUQ", s2 = "WOW NEUQ";
while (getline(cin, str))
{
if (str == "#") break;
vec.push_back(str);
// 把str放进istringstream流,这样就能依次读取每个string了
istringstream is(str);
string s;
while (is >> s)
{
if (s != s1)
{
// 把所有的字符都变成大写
transform(s.begin(), s.end(), s.begin(), ::toupper);
if (s == s1) ans++;
}
}
}
cout << ans << '\n';
for (int i = 0; i < vec.size(); i++)
{
istringstream is(vec[i]);
string s;
while (is >> s)
{
if (s == s1) cout << s2 << ' ';
else cout << s << ' ';
}
cout << '\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
深搜,枚举每一种合法选择,然后取最大值
#include
#define int long long
#define x first
#define y second
using namespace std;
int n, a, b, c;
int ans = 0;
struct node
{
int x, y, z, w;
}nodes[20];
void dfs(int u, int x, int y, int z, int cnt)
{
if (u == n)
{
ans = max(ans, cnt);
return;
}
// 如果能吃,就加上然后继续搜下一个
if (x + nodes[u].x <= a && y + nodes[u].y <= b && z + nodes[u].z <= c)
dfs(u + 1, x + nodes[u].x, y + nodes[u].y, z + nodes[u].z, cnt + nodes[u].w);
// 如果不能吃,就直接搜下一个
dfs(u + 1, x, y, z, cnt);
}
void solve()
{
cin >> n >> a >> b >> c;
for (int i = 0; i < n; i++)
{
int x, y, z, w;
cin >> x >> y >> z >> w;
nodes[i] = {x, y, z, w};
}
dfs(0, 0, 0, 0, 0);
cout << ans << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
二分,对于每一个位置,找到它最前面的合法的位置,这样的一个区间,然后取最大值
#include
#define int long long
#define x first
#define y second
using namespace std;
void solve()
{
int n, m;
cin >> n >> m;
vector<int> a(n + 1), sum(n + 1), res(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
// sum是素包子的前缀和
for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + (a[i] == 0);
// res是肉包子的前缀和
for (int i = 1; i <= n; i++) res[i] = res[i - 1] + a[i];
int ans = 0;
for (int i = 1; i <= n; i++)
{
int l = 0, r = i;
while (l < r)
{
int mid = l + r >> 1;
// 判断素包子的个数是否小于等于m
if (sum[i] - sum[mid] <= m) r = mid;
else l = mid + 1;
}
ans = max(ans, res[i] - res[l]);
}
cout << ans << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
差分,把所有的不优雅的数都标记上,然后对于每一个询问都去扫一遍,然后把答案存起来,这样如果有相同的询问就可以直接输出减少复杂度
#include
#define int long long
#define x first
#define y second
using namespace std;
void solve()
{
int n, m;
cin >> n >> m;
vector<int> a(1000010);
int maxx = 0;
for (int i = 0; i < n; i++)
{
int l, r;
cin >> l >> r;
// 差分操作
a[l] ++, a[r + 1] --;
// maxx是区间右边界的最大值
maxx = max(maxx, r);
}
// 前缀和恢复原数组
for (int i = 1; i < 1000010; i++) a[i] += a[i - 1];
// s1是优雅的,s2是不优雅的
set<int> s1, s2;
while (m--)
{
int x;
cin >> x;
// 如果答案集合里面有就直接输出
if (s1.count(x))
{
cout << "YES" << '\n';
continue;
}
if (s2.count(x))
{
cout << "NO" << '\n';
continue;
}
bool flag = true;
// 扫描数组,maxx是区间的最大值,大于这个还没找到就肯定是优雅的了
for (int i = x; i <= maxx; i += x)
if (a[i])
{
flag = false;
break;
}
// 判断完放入集合
if (flag)
{
s1.insert(x);
cout << "YES" << '\n';
}
else
{
s2.insert(x);
cout << "NO" << '\n';
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
注意数据范围 T T T 很大,所以肯定会出现循环的情况,我们可以找到这个环,然后进行数学运算即可
#include
#define int long long
#define x first
#define y second
using namespace std;
void solve()
{
int n, p, k, b, t;
cin >> n >> p >> k >> b >> t;
vector <int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
// s用来标记下标,如果标记存在还要插入就代表出现环了
set<int> s;
// vec用来存下标的执行顺序
vector<int> vec;
int x = 0;
// 这个循环是为了找最小环
while (t--)
{
if (s.count(p)) break;
s.insert(p);
vec.push_back(p);
x = x + a[p];
p = (k * p + b) % n;
}
// 如果发现没有环,直接输出即可
if (t == -1)
{
cout << x;
return;
}
// 如果发现有环了,就需要求出环的权值总和
t++;
int sum = 0, i;
for (i = vec.size() - 1; i >= 0; i--)
{
sum += a[vec[i]];
if (vec[i] == p) break;
}
x += (t / (vec.size() - i)) * sum;
t %= (vec.size() - i);
while (t--)
{
x += a[vec[i]];
i++;
}
cout << x << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
经典DP求方案数,
状态表示: d p [ i ] dp[i] dp[i], i i i 这个数有多少拆分方案
状态转移: d p [ j ] = d p [ j ] + d p [ j − i ] dp[j] = dp[j] + dp[j - i] dp[j]=dp[j]+dp[j−i]
物理意义就是对于某个数 j j j 都可以从比它小的数 j − i j-i j−i 的所有拆分方案后再加上 i i i 得到
#include
#define int long long
#define x first
#define y second
using namespace std;
const int mod = 998244353;
void solve()
{
int n;
cin >> n;
vector<int> dp(n + 1);
dp[0] = 1;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
dp[j] = (dp[j] + dp[j - i]) % mod;
cout << dp[n] << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}