第九屆河南理工大學算法程序設計大賽

一邊監考一邊寫了幾個題。一隊出的題目挺好的。總的來說,題目不難,但是坑點比較多,細心點才能做好。

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章