A_數字方陣
思路
假如 我們按照
1 2 3
4 5 6
7 8 9
就會發現 每一行 每一列 都不一樣 但是 兩條對角線上的元素是一樣的
這樣的話
1 2 7
3 4 8
5 6 9
我將前兩列按照 這樣的順序 排 然後最後一排改一下 就可以了。
其實不一定是這樣 還是有很多其它排列的方法的
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3 + 10;
const int MOD = 1e9 + 7;
int G[maxn][maxn];
int main()
{
int n;
scanf("%d", &n);
int pos = 1;
for (int i = 0; i < n; i++)
for (int j = 0; j < n - 1; j++)
G[i][j] = pos++;
for (int i = 0; i < n; i++)
G[i][n - 1] = pos++;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
printf("%d%c", G[i][j], (j == n - 1) ? '\n' : ' ');
}
B_小馬過河
思路
其實問題就是 給出一個點P 給出一條線 L 找出一條線 L’ 使得 L’ 經過點P 並且垂直於線L 然後求出 兩線交點就可以
假如線L 的一般式爲 Ax+By+c = 0
那麼垂直於線L的直線束就是 Bx - Ay + m = 0
那麼把點P 代入直線束 就可以求出參數m 也就得到 兩條線了 再求交就可以
那麼問題來了
給出兩點 怎麼求一條線L的一般式呢
參考博客
http://www.cnblogs.com/DHUtoBUAA/p/8057056.html
A=Y2-Y1
B=X1-X2
C=X2*Y1-X1*Y2
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;
int main()
{
int t;
cin >> t;
while (t--)
{
double px, py, ux, uy, vx, vy;
scanf("%lf%lf%lf%lf%lf%lf", &px, &py, &ux, &uy, &vx, &vy);
double A = vy - uy;
double B = ux - vx;
double C = vx * uy - ux * vy;
double m = A * py - B * px;
double y = (A * m - B * C) / (A * A + B * B);
double x = (A * y - m) / B;
printf("%.7lf %.7lf\n", x, y);
}
}
C_真真假假
思路
這個其實很簡單 ,把所有頭文件用map 標記一下 然後每次輸入 都查找一下是否存在就可以了
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 20 + 10;
const int MOD = 1e9 + 7;
map <string, int> m;
void init()
{
m["algorithm"] = 1;
m["bitset"] = 1;
m["cctype"] = 1;
m["cerrno"] = 1;
m["clocale"] = 1;
m["cmath"] = 1;
m["complex"] = 1;
m["cstdio"] = 1;
m["cstdlib"] = 1;
m["cstring"] = 1;
m["ctime"] = 1;
m["deque"] = 1;
m["exception"] = 1;
m["fstream"] = 1;
m["functional"] = 1;
m["limits"] = 1;
m["list"] = 1;
m["map"] = 1;
m["iomanip"] = 1;
m["ios"] = 1;
m["iosfwd"] = 1;
m["iostream"] = 1;
m["istream"] = 1;
m["ostream"] = 1;
m["queue"] = 1;
m["set"] = 1;
m["sstream"] = 1;
m["stack"] = 1;
m["stdexcept"] = 1;
m["streambuf"] = 1;
m["string"] = 1;
m["utility"] = 1;
m["vector"] = 1;
m["cwchar"] = 1;
m["cwctype"] = 1;
}
int main()
{
init();
int t;
cin >> t;
while (t--)
{
string s;
cin >> s;
puts(m[s]?"Qian":"Kun");
}
}
D_虛虛實實
思路
這個其實就是判斷一下給的無向圖是不是歐拉通路
只需要判斷一下 點的度數爲奇數的個數 是否等於0 或者 等於2 是的話 就是歐拉通路 不是的話 就不是
這個給出的圖不一定是連通的
所以首先要判斷一下圖的連通性 如果圖不連通 那肯定不是歐拉通路
用 DFS BFS 判斷都可以
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
//#define bug puts("***bug***");
#define bug
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 2e2 + 10;
const int MOD = 1e9 + 7;
int du[maxn];
int visit[maxn];
int G[maxn][maxn];
int flag;
int n, m;
void bfs()
{
queue <int> q;
q.push(1);
visit[1] = 1;
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = 1; i <= n; i++)
{
if (visit[i] == 0 && G[u][i] == 1)
{
visit[i] = 1;
flag++;
q.push(i);
}
}
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
du[i] = 0, visit[i] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
G[i][j] = G[j][i] = 0;
int x, y;
for (int i = 0; i < m; i++)
{
scanf("%d%d", &x, &y);
G[x][y] = G[y][x] = 1;
du[x]++, du[y]++;
}
int tot = 0;
flag = 1;
bfs();
for (int i = 1; i <= n; i++)
tot += (du[i] & 1);
if ((tot == 0 || tot == 2) && flag == n)
puts("Zhen");
else
puts("Xun");
}
}
E_是是非非
思路
題目其實是Nim博弈的變形
我們知道 Nim 博弈的 判斷方法 是將每堆石子的數量異或起來 如果最後異或值爲0 那麼先手的人就沒有必勝策略 反之則有
這題中的意思是 每次更改其中一堆 然後再判斷
如果每次更改一堆後 再重新異或判斷 會T
那麼怎麼辦呢
其實異或是有消去律的
也就是說 異或自己兩次 就 相當於沒有異或
所以 我們可以再輸入過程中 先把所有的值都異或一遍
這樣 我們就可以 在每次更改的基礎上 先異或沒有更改的那個值 來消去
再去更改那個值 再去異或 更改後的值 那麼就是我們要的最終的異或值了
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define bug
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;
int arr[maxn];
int main()
{
int n, q;
scanf("%d%d", &n, &q);
int ans = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &arr[i]);
ans ^= arr[i];
}
int x, y;
while (q--)
{
scanf("%d%d", &x, &y);
ans ^= arr[x];
arr[x] = y;
ans ^= arr[x];
puts(ans ? "Kan" : "Li");
}
}
F_黑黑白白
思路
對於這個問題,我們可以一層一層的看
比如題目給出的樣例當中
除了根節點
顯然 偶數層 就是先手的人的選擇
那麼 奇數層 便是後手的人的選擇
從奇數層下來 會有兩條路 這時候 是先手的人選擇 如果這個時候 有一條路是葉子節點了 那麼先手的人就是可以勝利的
這個時候 就返回答案就可以了 不用再往下搜了
那麼什麼時候 是後手的人可以獲勝的情況呢
就是 偶數層下來 兩個方向 後手的人在其中一個方向可以獲得勝利,那麼先手的人是沒有必勝策略的
比如下面這種情況
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
#define fi first
#define se second
//#define bug
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 1e4 + 10;
const int MOD = 1e9 + 7;
vector <int> edge[maxn];
int n, r;
bool dfs(int root, int pre)
{
int len = edge[root].size();
if (len == 0) return false;
for (int i = 0; i < len; i++)
{
int v = edge[root][i];
if (v == pre) continue;
if (dfs(v, root) == false) return true;
}
return false;
}
void clear()
{
for (int i = 1; i <= n; i++)
edge[i].clear();
}
int main()
{
int t;
cin >> t;
while (t--)
{
clear();
scanf("%d%d", &n, &r);
int len = n - 1;
int x, y;
for (int i = 0; i < len; i++)
{
scanf("%d%d", &x, &y);
edge[x].pb(y);
edge[y].pb(x);
}
puts(dfs(r, -1) ? "Gen" : "Dui");
}
}
G_文
思路
這個保存一下正確答案 然後將選手的答案 一個一個去比對就可以了
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 20 + 10;
const int MOD = 1e9 + 7;
int main()
{
int n, m;
scanf("%d%d", &n, &m);
string sta;
cin >> sta;
string ans = "zzzzzzzzzzzzzzzzz", tmp, tmm;
int Max = -INF;
for (int i = 0; i < m; i++)
{
int tot = 0;
cin >> tmp >> tmm;
for (int j = 0; j < n; j++)
if (tmm[j] == sta[j])
tot++;
if (tot > Max || (tot == Max && tmp < ans))
{
Max = tot;
ans = tmp;
}
}
cout << ans << endl;
printf("%.2lf\n", Max * 1.0 / n * 100.0);
}
H_武
思路
跑一下 Djikstra 然後 將dist 排序 輸出第K個就可以了
但是要注意 因爲N比較大 所以要存邊 然後用優先隊列優化 就能過
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
#define fi first
#define se second
//#define bug
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;
struct node
{
int v, c;
node(int _v = 0, int _c = 0) : v(_v), c(_c) {}
bool operator < (const node &r) const
{
return c > r.c;
}
};
struct Edge
{
int v, cost;
Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost){}
};
vector <Edge> E[maxn];
bool vis[maxn];
int dist[maxn];
void dijkstra(int n, int start)
{
CLR(vis, false);
for (int i = 1; i <= n; i++) dist[i] = INF;
priority_queue <node> que;
while (!que.empty()) que.pop();
dist[start] = 0;
que.push(node(start, 0));
node tmp;
while (!que.empty())
{
tmp = que.top();
que.pop();
int u = tmp.v;
if (vis[u]) continue;
vis[u] = true;
int len = E[u].size();
for (int i = 0; i < len; i++)
{
int v = E[tmp.v][i].v;
int cost = E[u][i].cost;
if (!vis[v] && dist[v] > dist[u] + cost)
{
dist[v] = dist[u] + cost;
que.push(node(v, dist[v]));
}
}
}
}
void addedge(int u, int v, int w)
{
E[u].pb(Edge(v, w));
}
int main()
{
int n, p, k;
scanf("%d%d%d", &n, &p, &k);
int len = n - 1;
int u, v, w;
while (len--)
{
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
addedge(v, u, w);
}
dijkstra(n, p);
sort(dist + 1, dist + 1 + n);
printf("%d\n", dist[k + 1]);
}
I_藝
思路
這個只需要判斷一下 每分鐘哪個節目的愉悅度高 就看哪個就好了 For 幾遍 複雜度O(n)
但是要注意 如果兩個愉悅度都是負的 那麼可以選擇這時刻不看 也就是 愉悅度爲0
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
//#define bug
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;
struct node
{
int s, e, v;
node() {}
node(int _s, int _e, int _v) : s(_s), e(_e), v(_v) {}
bool operator < (const node& r) const
{
return s < r.s;
}
void read()
{
scanf("%d%d", &s, &v);
}
}a[maxn], b[maxn];
int main()
{
int n, m, t;
scanf("%d%d%d", &n, &m, &t);
for (int i = 0; i < n; i++)
a[i].read();
for (int i = 0; i < m; i++)
b[i].read();
sort(a, a + n);
sort(b, b + m);
a[n].s = b[m].s = t;
for (int i = 0; i < n; i++)
a[i].e = a[i + 1].s;
for (int i = 0; i < m; i++)
b[i].e = b[i + 1].s;
ll ans = 0;
for (int i = 1, j = 0, k = 0; i <= t; i++)
{
if (a[j].e < i) j++;
if (b[k].e < i) k++;
ans += max(a[j].v, max(b[k].v, 0));
}
cout << ans << endl;
}
J_美
思路
這個就是儘量讓相鄰的兩個人帥氣值儘量差距大就可以了
那麼顯然 先排序
先放一個最小的 再放一個最大的 這樣放下去。。
比如 樣例中
5
7 3 15 12 8
排序後就是
3 8 7 12 15
按照那種排放方式 排放下來就是
3 15 7 12 8
AC代碼
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
//#define bug puts("***bug***");
#define bug
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;
int a[maxn], b[maxn];
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
sort(a, a + n);
for (int i = 0, j = n - 1, pos = 0; pos < n; i++, j--)
{
b[pos++] = a[i];
if (pos < n)
b[pos++] = a[j];
}
ll ans = 0;
for (int i = 1; i < n; i++)
ans += abs(b[i] - b[i - 1]);
ans += b[n - 1] - b[0];
printf("%lld\n", ans);
}