一邊監考一邊寫了幾個題。一隊出的題目挺好的。總的來說,題目不難,但是坑點比較多,細心點才能做好。
A. Asia區域賽
簽到題:
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
#define line cout<<"--------------"<<endl
typedef long long ll;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int main(){
cout << 29+58+87+13 << endl;
return 0;
}
B. Asia區域制
二進制轉換十進制,注意數據的範圍很大。所以先把二進制轉化爲long long 類型的10進制數再轉化爲16進制字符串是錯誤的。
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
typedef long long ll;
const int maxn = 1e6 + 10;
void solve(string c){
if(c == "0000") printf("0");
else if(c == "0001")printf("1");
else if(c == "0010")printf("2");
else if(c == "0011")printf("3");
else if(c == "0100")printf("4");
else if(c == "0101")printf("5");
else if(c == "0110")printf("6");
else if(c == "0111")printf("7");
else if(c == "1000")printf("8");
else if(c == "1001")printf("9");
else if(c == "1010")printf("a");
else if(c == "1011")printf("b");
else if(c == "1100")printf("c");
else if(c == "1101")printf("d");
else if(c == "1110")printf("e");
else if(c == "1111")printf("f");
}
int main(){
int t;
scanf("%d", &t);
getchar();
while(t--){
string s;
cin >> s;
int len = s.length();
if(len % 4 == 1) s = "000" + s;
else if(len % 4 == 2) s = "00" + s;
else if(len % 4 == 3) s = "0" + s;
len = s.length();
for(int i = 0; i < len; i+=4){
string x;
for(int j = 0; j < 4; j++){
x += s[i+j];
}
solve(x);
}
printf("\n");
}
return 0;
}
C. Asia區域宮
表面上看是個BFS求最短路徑,仔細看一下數據發現巨jb大,所以bfs 是不可行的。
觀察題目:障礙物在迷宮中不能同行且不能同列。
所以。如果不能到達終點,圖中只能是從左下到右上的牆。所以,標記每條斜線上的牆壁個數就好了。
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
typedef long long ll;
const int maxn = 1e6 + 10;
const int N = 10001;
int n, m, x, y, t, a[N];
int main(){
scanf("%d", &t);
while(t--){
bool flag = true;
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
scanf("%d%d", &x, &y);
int tes = x + y - 1;
a[tes] ++;
if(a[tes] >= tes) {
flag = false;
}
}
if(flag) printf("Yes %d\n", (n-1)*2);
else printf("No\n");
clr(a);
}
return 0;
}
D. Asia區域陣
待補
E. Mo的遊戲
用一個數組標記一下上一次出現字符的位置,然後在遍歷一遍選出最大的
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
#define line cout<<"--------------"<<endl
typedef long long ll;
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
char s[maxn];
int a[26], A[26];
int an[26], An[26];
int main(){
scanf("%s", s);
int len = strlen(s);
for(int i = 0; i < 26; i++){
a[i] = -1; A[i] = -1;
an[i] = len; An[i] = len;
}
for(int i = 0; i < len; i++){
if(s[i] >= 'a' && s[i] <='z'){
if(a[s[i]-'a'] == -1) a[s[i]-'a'] = i;
else{
int pos = i - a[s[i]-'a'];
an[s[i]-'a'] = min(an[s[i]-'a'], pos);
a[s[i]-'a'] = i;
}
}
else{
if(A[s[i]-'A'] == -1) A[s[i]-'A'] = i;
else{
int pos = i - A[s[i]-'A'];
An[s[i] - 'A'] = min(An[s[i] - 'A'], pos);
A[s[i]-'A'] = i;
}
}
}
for(int i = 0; i < 26; i++){
if(a[i] == -1 || an[i] == INF) continue;
else printf("%c:%d\n", 'a'+i, len-an[i]);
}
for(int i = 0; i < 26; i++){
if(A[i] == -1) continue;
else printf("%c:%d\n", 'A'+i, len-An[i]);
}
return 0;
}
F. Mo的極限
這個題出得很李戰士。
要注意-0x^k 以及 同類項的合併。
G. Mo的數學
正解爲容斥定理,我用的質因數分解+打標記水過
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
#define line cout<<"--------------"<<endl
typedef long long ll;
const ll maxn = 1e6 + 10;
const ll INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
bool vis[maxn];
ll a[maxn];
ll n, m, num;
void get_factor(int x){
for(int i = 2; i*i <= x; i++){
if(x % i == 0){
a[num++] = i;
while(x % i == 0){
x /= i;
}
}
}
if(x != 1) a[num++] = x;
}
int main(){
while(scanf("%d%d", &n, &m) != EOF){
clr(a); num = 0;
memset(vis, 1, sizeof(vis));
get_factor(m);
//line;
ll ans = 1;
for(int i = 0; i < num; i++){
ll t = a[i];
for(int j = 1; t*j <= n; j++){
vis[t*j] = false;
}
}
for(int i = 2; i <= n; i++){
if(vis[i]) ans = ((ans % MOD )* (i % MOD )) % MOD;
}
printf("%lld\n", ans);
}
return 0;
}
H. Mo的面積
簡單計算幾何
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
#define line cout<<"--------------"<<endl
typedef long long ll;
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int main(){
int x1,x2,y1,y2;
int q1,q2,w1,w2;
while(cin>>x1>>y1>>x2>>y2>>q1>>w1>>q2>>w2){
int xx=max(min(x1,x2),min(q1,q2));
int yy=max(min(y1,y2),min(w1,w2));
int xxup=min(max(x1,x2),max(q1,q2));
int yyup=min(max(y1,y2),max(w1,w2));
int ans = 0;
if(xxup>xx)
ans = fabs((xx)-(xxup))*fabs((yy)-(yyup));
int a = fabs(x1-x2) * fabs(y1-y2);
int b = fabs(q1-q2) * fabs(w1-w2);
ans = a + b - ans;
cout << ans << endl;
}
}
I. 安全距離
高級計算幾何,待補
J. 簡單遞歸
簽到題
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
#define line cout<<"--------------"<<endl
typedef long long ll;
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = (int)1e9 + 7;
int main(){
int t;
cin >> t;
int a[maxn];
a[0] = a[1] = a[2] = 1;
for(int i = 3; i <maxn; i++){
a[i] = ((a[i-1] << 1) % MOD + (a[i-2] >> 1)) % MOD;
}
while(t--){
int n;
scanf("%d", &n);
printf("%d\n",a[n]);
}
return 0;
}
K. 高度期望
簽到題
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
#define line cout<<"--------------"<<endl
typedef long long ll;
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int n, num = 0, k, a[maxn];
int main(){
ll sum = 0;
cin >> n >> k;
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
sum += a[i];
}
sort(a, a+n);
while(sum < k * n){
sum += (1000-a[num]);
num++;
}
cout << num << endl;
return 0;
}
L. 最優規劃
最小生成樹模板,
#include<bits/stdc++.h>
using namespace std;
#define clr(a) memset(a, 0, sizeof(a))
#define line cout<<"--------------"<<endl
typedef long long ll;
const ll maxn = 1e6 + 10;
const ll INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ll N = 100010;
ll n, m, s;
ll x, y, d;
ll pre[N];
struct node{
ll x, y, d;
}p[N];
ll find(ll x){
if(x == pre[x]) return x;
else return pre[x] = find(pre[x]);
}
void mix(ll x, ll y){
ll dx = find(x);
ll dy = find(y);
if(dx != dy) pre[dx] = dy;
}
bool cmp(node a, node b){
return a.d < b.d;
}
int main(){
scanf("%lld%lld%lld", &n, &m, &s);
for(ll i = 0; i <= n; i++){
pre[i] = i;
}
for(ll i = 0; i < m; i++){
scanf("%lld%lld%lld", &x, &y, &d);
mix(x, y);
}
for(ll i = 0; i < s; i++){
scanf("%lld%lld%lld", &p[i].x, &p[i].y, &p[i].d);
}
sort(p, p+s, cmp);
ll sum = 0;
bool flag = false;
for(ll i = 0; i < s; i++){
ll dx = find(p[i].x);
ll dy = find(p[i].y);
if(dx != dy){
sum += p[i].d;
pre[dx] = dy;
}
}
ll cnt = 0;
for(ll i = 1; i <= n; i++){
if(i == find(i)) cnt++;
}
if(cnt == 1) printf("%lld\n", sum);
else printf("Concubines can't do it.\n");
return 0;
}