题解:将所有的头文件弄成一个字符串,然后直接用find()函数搜,简单粗暴,不愧是签到题
#include
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string s = "algorithmbitsetcctypecerrnoclocalecmathcomplexcstdiocstdlibcstringctimedequeexceptionfstreamfunctionallimitslistmapiomanipiosiosfwdiostreamistreamostreamqueuesetsstreamstackstdexceptstreambufstringutilityvectorcwcharcwctype";
int _;
cin >> _;
while (_--) {
string str;
cin >> str;
if (s.find(str) != s.npos) cout << "Qian" << endl;
else cout << "Kun" << endl;
}
return 0;
}
原理:经典尼姆博弈
结论:
#include
using namespace std;
const int N = 100010;
int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, _;
cin >> n >> _;
int xx = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
xx ^= a[i];
}
while (_--) {
int x, y;
cin >> x >> y;
int t = a[x] ^ y;
xx ^= t;
a[x] = y;
if (xx) cout << "Kan" << endl;
else cout << "Li" << endl;
}
return 0;
}
排名规则:分数优先,分数相同则按名字的字典序排名。
然后就上Code~,最后注意一下输出即可。
#include
using namespace std;
const int N = 100010;
int a[N];
int n, m;
string ans;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
cin >> ans;
int cnt = -1;
string tname;
while (m--) {
string name, a;
cin >> name;
cin >> a;
int len = 0;
for (int j = 0; j < n; j++) {
if (a[j] == ans[j]) len++;
}
if (len > cnt) {
tname = name;
cnt = len;
} else if (len == cnt && tname > name) {
tname = name;
cnt = len;
}
}
double res = 100;
cout << tname << endl;
printf("%.2lf\n", res * cnt * 1.0 / n);
return 0;
}
题解:
P(px, py),U(ux, uy),V(vx, vy)
有三个点的位置,通过U,V两个点的坐标可以求出直线UV的斜率k1
直线UV中:有斜率,有点的坐标,可以通过点斜式写出直线UV的解析式
过P点,作PA⊥UV通过两直线垂直,k1·k2 = -1,求出直线PA的斜率k2
直线PA通过点P(px,py) 那么也可以通过点斜式写出直线PA的解析式
直线UV和直线PA的交点即 要求的垂足。
特殊情况,特殊判断:uxyx,uyvy
常规情况:
直线UV: k = v y − v x u y − u x k=\frac{vy-vx}{uy-ux} k=uy−uxvy−vx
直线UV通过v点且斜率为k
直线UV的解析式: y − v y = k ( x − v x ) y-vy=k(x-vx) y−vy=k(x−vx)
过P点,作PA⊥UV通过两直线垂直,则直线UV的斜率为 − 1 k -\frac{1}{k} −k1
直线PA的解析式: y − p y = − 1 k ( x − p x ) y-py=-\frac{1}{k}(x-px) y−py=−k1(x−px)
联立直线UV和PA:
v y + k ( x − v x ) = p y + [ − 1 k ( x − p x ) ] v_y+k(x-v_x)=p_y+[-\frac{1}{k}(x-p_x)] vy+k(x−vx)=py+[−k1(x−px)]
v y + k x − k v x = p y − x k + p x k v_y+kx-kv_x=p_y-\frac{x}{k}+\frac{p_x}{k} vy+kx−kvx=py−kx+kpx
( k + 1 k ) x = p y − v y + k v x + p x k (k+\frac{1}{k})x=p_y-v_y+kv_x+\frac{p_x}{k} (k+k1)x=py−vy+kvx+kpx
x = p y − v y + k v x + p x k k 2 + 1 k x=\frac{p_y-v_y+kv_x+\frac{p_x}{k}}{\frac{k^2+1}{k}} x=kk2+1py−vy+kvx+kpx
x = k 2 v x − k v y + p x + k p y k 2 + 1 x = \frac{k^2v_x-kv_y+p_x+kp_y}{k^2+1} x=k2+1k2vx−kvy+px+kpy
y = k ( x − v x ) + v y y = k(x-v_x)+v_y y=k(x−vx)+vy
#include
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _;
cin >> _;
while (_--) {
double px, py, ux, uy, vx, vy;
cin >> px >> py >> ux >> uy >> vx >> vy;
if (ux == vx) printf("%.7lf %.7lf\n", ux, py);
else if (uy == vy) printf("%.7lf %.7lf\n", px, uy);
else {
double k = (vy - uy) / (vx - ux);
double x = (k * k * vx - k * vy + px + k * py) / (k * k + 1);
double y = k * (x - vx) + vy;
printf("%.7lf %.7lf\n", x, y);
}
}
return 0;
}
相关概念:
欧拉路径:图中的一条路径,这个路径通过图中的每一条边,并且每条边仅通过一次。
欧拉回路:闭合的欧拉路径
欧拉图:包含欧拉回路的图
通俗的解释:欧拉路径即一笔画问题,一笔画的路径叫做欧拉路径,如果最后一笔回到起点,那么这个路径叫做欧拉回路
这道题两个条件:
满足上述两个条件即可,并查集判断
#include
using namespace std;
const int N = 50;
int f[N], e[N];
void init () {
memset(e, 0, sizeof e);
for (int i = 1; i <= N; i++) {
f[i] = i;
}
}
int find(int x) {
return x == f[x] ? x : f[x] = find(f[x]);
}
int main()
{
int _;
cin >> _;
while (_--) {
init();
int n, m;
cin >> n >> m;
int root = 0;
int du = 0;
while (m--) {
int u, v;
cin >> u >> v;
int fu = find(u);
int fv = find(v);
if (fu != fv) f[fu] = fv;
//记录 度
e[u]++;
e[v]++;
}
for (int i = 1; i <= n; i++) {
if (e[i] % 2) du++;
if (f[i] == i) root++;//起点
}
if (root == 1 && du <= 2) cout << "Zhen" << endl;
else cout << "Xun" << endl;
}
return 0;
}
建图,存每个点的距离,排序,输出第K近的即可
#include
using namespace std;
const int N = 200010;
int n, m, k;
int u, v, p;
int dist[N], h[N], e[N], ne[N], w[N], idx;
void add(int a, int b, int c) {
w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u, int dis, int f) {
dist[u] = dis;
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (j == f) continue;
dfs(j, dis + w[i], u);
}
}
int main()
{
cin >> n >> m >> k;
memset(h, -1, sizeof h);
for (int i = 1; i < n; i++) {
cin >> u >> v >> p;
add(u, v, p);
add(v, u, p);
}
dfs(m, 0, -1);
sort(dist + 1, dist + n + 1);
cout << dist[k + 1] << endl;
return 0;
}
从左上角开始,由左到右,由上到下,从1填到 n ( n − 1 ) n(n-1) n(n−1),最后一列,从 n ( n − 1 ) + 1 n(n-1)+1 n(n−1)+1 到 n 2 n^2 n2
#include
using namespace std;
const int N = 1010;
int a[N][N];
int main()
{
int n;
cin >> n;
int x = 0, y = n * (n - 1) + 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j < n; j++) {
a[i][j] = ++x;
}
}
for (int i = 1; i <= n; i++) a[i][n] = ++x;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << a[i][j] << ' ';
}
cout << endl;
}
return 0;
}
题解:建树,然后从根节点开始搜索,只要找到一条能赢的路就可以。
#include
using namespace std;
const int N = 500010;
int h[N], e[N], ne[N], idx;
int t;
int n, r;
int u, v;
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int dfs(int u, int f) {
int cur = 0;
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (j == f) continue;
if (!dfs(j, u)) return 1;
}
return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t--) {
cin >> n >> r;
memset(h, -1, sizeof h);
for (int i = 1; i < n; i++) {
cin >> u >> v;
add(u, v);
add(v, u);
}
if (dfs(r, -1)) cout << "Gen" << endl;
else cout << "Dui" << endl;
}
return 0;
}
选美大赛,这套题有点阴间
题意,要求选出差值的和最大,依旧是构造题
构造:一个最大,一个最小,一个次大,一个次小 … 以此类推,这样的差之和最大。
举例:1 2 3 4 5
结果:5 1 4 2 3
注意:当 i = 1时,R0 = Rn
,所以初始化 ans = abs(b[1] - b[n])
那么就是注意一下下标即可。
#include
#define endl '\n'
#define int long long
using namespace std;
const int N = 100010;
int a[N], b[N];
int n;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
int idx = 0;
for(int i = 1; i <= n; i += 2) b[i] = a[++idx];
if (n % 2) {
for (int i = n - 1; i > 0; i -= 2) b[i] = a[++idx];
} else {
for (int i = n; i > 0; i -= 2) b[i] = a[++idx];
}
// for (int i = 1; i <= idx; i++) cout << b[i] << ' ';
// cout << endl;
int ans = abs(b[1] - b[n]);
for (int i = 2; i <= n; i++) ans += abs(b[i] - b[i - 1]);
cout << ans << endl;
return 0;
}