zoukankan      html  css  js  c++  java
  • 2018 JUST Programming Contest 1.0 题解

    题目链接  gym101778

    Problem A

    转化成绝对值之后算一下概率。这个题有点像 2018 ZOJ Monthly March Problem D ? 不过那个题要难一些~

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    const LL mod = 1e9 + 7;
    const int N  = 2e5 + 10;
    
    
    int T;
    int n, m;
    LL fac[N];
    
    inline LL Pow(LL a, LL b, LL mod){
            LL ret(1);
            for (; b; b >>= 1, (a *= a) %= mod) if (b & 1) (ret *= a) %= mod;
            return ret;
    }
    
    inline LL C(LL n, LL m){ return m > n ? 0 : fac[n] * Pow(fac[m] * fac[n - m] % mod, mod - 2, mod) % mod; }
    
    
    int main(){
    
    	fac[0] = 1;
    	rep(i, 1, 2e5 + 1) fac[i] = fac[i - 1] * 1ll * i % mod; 
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%d", &n, &m);
    		n = abs(n);
    
    		if (n == 0 && m == 0){
    			puts("1");
    			continue;
    		}
    		
    		if (m < n){
    			puts("0");
    			continue;
    		}
    
    		if ((m + n) % 2 == 1){
    			puts("0");
    			continue;
    		}
    
    		int x = (m + n) / 2;
    		printf("%lld
    ", C(m, x) * Pow(Pow(2, m, mod), mod - 2, mod) % mod);
    	}
    
    	return 0;
    }

    Problem B

    把首项定成$1$然后二分答案就可以了

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    int T;
    LL n, a, l, r, t;
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%lld%lld", &n, &a);
    
    		l = 0, r = n;
    		
    		while (l + 1 < r){
    			LL mid = (l + r) >> 1;
    			if (mid * (mid + 1) / 2ll <= n * a - n + mid) l = mid;
    			else r = mid - 1;
    		}
    		
    		if (r * (r + 1) / 2ll <= n * a - n + r) t = r;
    		else t = l;
    
    		printf("%lld
    ", t);
    	}
    
    	return 0;
    }

    Problem C

    找规律。$ans = (n - 1) * phi(n)$

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    typedef long long LL;
    
    const int N = 1e6 + 10;
    
    int T;
    int phi[N];
    int n;
    
    
    int main(){
    
    	rep(i, 2, 1e6 + 1){
    		if (!phi[i]){
    			for (int j = i; j <= 1e6; j += i){
    				if (!phi[j]) phi[j] = j;
    				phi[j] -= phi[j] / i;
    			}
    		}
    	}
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d", &n);
    		printf("%lld
    ", 1ll * (n - 1) * phi[n]);
    	}
    
    	return 0;
    }

    Problem D

    状态压缩,对于每一个集合求MST

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    const int N = 16;
    
    int T;
    int n, m, k;
    int a[N][N], c[1 << N];
    int all;
    int ans;
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%d%d", &n, &m, &k);
    		memset(c, 0, sizeof c);
    		memset(a, -1, sizeof a);
    
    		ans = 2e9;
    
    		rep(i, 1, m){
    			int x, y, z;
    			scanf("%d%d%d", &x, &y, &z);
    			--x;
    			--y;
    			a[x][y] = a[y][x] = z;
    		}
    
    		all = 0;
    		rep(i, 1, k){
    			int x;
    			scanf("%d", &x);
    			--x;
    			all |= (1 << x);
    		}
    
    		int mx = (1 << n) - 1;
    		rep(i, 1, mx){
    			c[i] = 2e9;
    			int p = 0;
    			dec(j, n - 1, 0) if ((i >> j) & 1){
    				p = j;
    				break;
    			}
    
    			if ((i ^ (1 << p)) == 0){
    				c[i] = 0;
    				continue;
    			}
    
    			dec(j, n - 1, 0){
    				if ((i >> j) & 1){
    					rep(k, 0, n - 1){
    						if (((i >> k) & 1) && (j != k) && (~a[j][k])) c[i] = min(c[i], c[i ^ (1 << j)] + a[j][k]);
    					}
    				}
    			}
    		}
    
    		rep(i, 1, mx) if ((i & all) == all) ans = min(ans, c[i]);
    		printf("%d
    ", ans);
    	}
    
    	return 0;
    }

    Problem E

    直接模拟

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define	dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define	fi		first
    #define	se		second
    #define	MP		make_pair
    
    typedef long long LL;
    
    int T;
    int n, x, y;
    int id, d, m;
    int mxd, mxm;
    
    int main(){
    
    	scanf("%d", &T);
    
    	while (T--){
    		scanf("%d%d%d", &n, &x, &y);
    
    		mxd = 1e9, mxm = 0;
    		id = -1;
    		rep(i, 1, n){
    			scanf("%d%d", &d, &m);
    			if (d <= x && m >= y){
    				if (mxd > d || (mxd == d && mxm < m)){
    					mxd = d;
    					mxm = m;
    					id  = i;
    				}
    			}
    		}
    
    		printf("%d
    ", id);
    	}
    
    	return 0;
    
    }

    Problem F

    这个题略卡常数。

    对每个权值求二维前缀和,二分答案就好了。

    #include <bits/stdc++.h>
    
    namespace IO{
    	const int MT = 20 * 1024 * 1024; 
    	char IO_BUF[MT];
    	int IO_PTR, IO_SZ;
    
    	void begin(){
    		IO_PTR = 0;
    		IO_SZ = fread (IO_BUF, 1, MT, stdin);
    	}
    	template<typename T>
    		inline bool scan_d (T & t){
    			while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != '-' && (IO_BUF[IO_PTR] < '0' || IO_BUF[IO_PTR] > '9'))IO_PTR ++;
    			if (IO_PTR >= IO_SZ) return false;
    			bool sgn = false;
    			if (IO_BUF[IO_PTR] == '-') sgn = true, IO_PTR ++;
    			for (t = 0; IO_PTR < IO_SZ && '0' <= IO_BUF[IO_PTR] && IO_BUF[IO_PTR] <= '9'; IO_PTR ++)
    				t = t * 10 + IO_BUF[IO_PTR] - '0';
    			if (sgn) t = -t;
    			return true;
    
    		}
    };
    
    using namespace IO;
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    const int M = 503;
    const int N = 1e2 + 2;
    
    int c[M][N][N];
    int a[N][N];
    int n, m, q;
    int mx;
    int T;
    
    
    int calc(int x1, int y1, int x2, int y2, int val){
    	return c[val][x2][y2] - c[val][x2][y1 - 1] - c[val][x1 - 1][y2] + c[val][x1 - 1][y1 - 1];
    }
    
    void print(int x){
    	if (x > 9) print(x / 10);
    	putchar(x % 10 + '0');
    }
    
    int main(){
    
    	begin();
    	scan_d(T);;
    	while (T--){
    		scan_d(n);
    		scan_d(m);
    		scan_d(q);
    
    		mx = 0;
    
    		rep(i, 1, n){
    			rep(j, 1, m) scan_d(a[i][j]), mx = max(mx, a[i][j]);
    		}
    
    		rep(k, 0, mx){
    			rep(i, 0, n + 1){
    				rep(j, 0, m + 1) c[k][i][j] = 0;
    			}
    		}
    
    		rep(k, 1, mx){
    			rep(i, 1, n){
    				rep(j, 1, m){
    					c[k][i][j] = c[k][i - 1][j] + c[k][i][j - 1] - c[k][i - 1][j - 1] + (a[i][j] <= k);
    				}
    			}
    		}
    
    
    		while (q--){
    			int x1, y1, x2, y2;
    			scan_d(x1);
    			scan_d(y1);
    			scan_d(x2);
    			scan_d(y2);
    
    			int all = (x2 - x1 + 1) * (y2 - y1 + 1);
    			all = (all + 1) / 2;
    
    			int l = 1, r = mx;
    
    			while (l + 1 < r){
    				int mid = (l + r) >> 1;
    				if (calc(x1, y1, x2, y2, mid) >= all) r = mid;
    				else l = mid + 1;
    			}
    
    			int t;
    			if (calc(x1, y1, x2, y2, l) >= all) t = l;
    			else t = r;
    
    			print(t);
    			putchar(10);
    		}
    	}
    	return 0;
    }

    Problem G

    根据割线定理来做。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define	dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define	fi		first
    #define	se		second
    #define	MP		make_pair
    
    typedef long long LL;
    
    int T;
    int n, x, y;
    int id, d, m;
    int mxd, mxm;
    
    int main(){
    
    	scanf("%d", &T);
    
    	while (T--){
    		scanf("%d%d%d", &n, &x, &y);
    		mxd = 1e9, mxm = 0;
    		id = -1;
    		rep(i, 1, n){
    			scanf("%d%d", &d, &m);
    			if (d <= x && m >= y){
    				if (mxd > d || (mxd == d && mxm < m)){
    					mxd = d;
    					mxm = m;
    					id  = i;
    				}
    			}
    		}
    
    		printf("%d
    ", id);
    	}
    
    	return 0;
    
    }

    Problem H

    假的数据结构……其实还是模拟

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    const int N = 1e5 + 10;
    
    int T;
    int n, m;
    char s[N], ch[2];
    
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%d", &n, &m);
    		scanf("%s", s + 1);
    
    		int c = 0;
    		rep(i, 1, (n + 1) >> 1) if (s[i] == s[n - i + 1]) ++c;
    		int all = (n + 1) >> 1;
    		
    		int ans = 0;
    
    		while (m--){
    			int x;
    			scanf("%d%s", &x, ch);
    			if (s[x] == s[n - x + 1]){
    				s[x] = ch[0];
    				if (s[x] != s[n - x + 1]) --c;
    			}
    
    			else{
    				s[x] = ch[0];
    				if (s[x] == s[n - x + 1]) ++c;
    			}
    
    			if (c == all) ++ans;
    		}
    
    		printf("%d
    ", ans);
    	}
    
    	return 0;
    }

    Problem I

    签到

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
    
    int T;
    
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		int a, b, c, d;
    		scanf("%d%d%d%d", &a, &b, &c, &d);
    
    		if (a == d && b == c){
    			puts("-1");
    			continue;
    		}
    
    		if (a + c == b + d){
    			if (c > a) puts("1"); else puts("2");
    		}
    
    		else if (a + c > b + d) puts("1");
    		else puts("2");
    	}
    
    	return 0;
    }

    Problem J

    挺有意思的一个题。

    其实暴力做就可以了。因为在1e9的范围内质数间隔最大大概只有$320$。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define	rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define	dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    typedef long long LL;
    
    int T;
    int fg;
    LL  l, r;
    
    bool check(LL x){
    	if (x <= 10) return false;
    	string s1 = "";
    
    	for (; x; x /= 10) s1 += x % 10 + '0';
    
    	reverse(s1.begin(), s1.end());
    
    	int n = s1.length();
    	string s2 = s1.substr(0, (n + 1) / 2);
    	string s3 = s1.substr((n + 1) / 2);
    
    	LL a = 0, b = 0;
    
    	for (auto u : s2) a = a * 10 + u - '0';
    	for (auto u : s3) b = b * 10 + u - '0';
    
    	return __gcd(a, b) == 1;
    }
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%lld%lld", &l, &r);
    		fg = 0;
    		for (LL i = r; i >= l; --i){
    			if (check(i)){
    				fg = 1;
    				printf("%lld
    ", i);
    				break;
    			}
    		}
    
    		if (!fg) puts("-1");
    	}
    
    	return 0;
    
    }

    Problem K

    模拟……

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    
    typedef long long LL;
     
    struct state{
    	int x, y, z, t;
    	state(){
    		x = y = z = t = -1;
    	}
    	state(int x, int y, int z, int t) :
    			x(x), y(y), z(z), t(t){
    	}
    	bool operator < (const state &e) const{
    		return t < e.t;
    	}
    };
     
    const int N = 1e2 + 2;
    
    
    int T;
    int n, m, k;
    int fb[N];
    int WA[N][N], FAC[N];
    vector <state> sub;
    
     
    int main(){
    	
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%d%d", &n, &m, &k);
    		int x, y, z, tm, ts;
    		sub.clear();
    		rep(i, 0, k - 1){
    			scanf("%d%d%d%d:%d", &x, &y, &z, &tm, &ts);
    			sub.push_back(state(x - 1, y - 1, z, tm * 60 + ts));
    		}
    		sort(sub.begin(), sub.end());
    		memset(fb, -1, sizeof fb);
    		memset(WA, 0, sizeof WA);
    		memset(FAC, 0, sizeof FAC);
    		int ep = -1, sg = -1;
    		pair<int, int> sp(-1, 0), rp(-1, 0);
    		rep(i, 0, k - 1){
    			if (sub[i].z == 0)
    				++WA[sub[i].x][sub[i].y];
    			else{
    				if (fb[sub[i].x] == -1)
    					fb[sub[i].x] = sub[i].y + 1;
    				if (ep == -1)
    					ep = sub[i].y + 1;
    				sg = sub[i].y + 1;
    				if (WA[sub[i].x][sub[i].y] == 0)
    					++FAC[sub[i].y];
    				if (FAC[sub[i].y] > sp.first || (FAC[sub[i].y] == sp.first && sub[i].y + 1 < sp.second))
    					sp = make_pair(FAC[sub[i].y], sub[i].y + 1);
    				if (WA[sub[i].x][sub[i].y] > rp.first || (WA[sub[i].x][sub[i].y] == rp.first && sub[i].y + 1 < rp.second))
    					rp = make_pair(WA[sub[i].x][sub[i].y], sub[i].y + 1);
    			}
    		}
    		rep(i, 0, n - 1) printf("%s%d", i ? " " : "", fb[i]);
    		putchar(10);
    		printf("%d %d %d %d
    ", ep, sg, sp.se, rp.se);
    	}
    	return 0;
    }
    

     

  • 相关阅读:
    codevs 1086 栈 2003年NOIP全国联赛普及组
    1200 同余方程 2012年NOIP全国联赛提高组
    【bzoj4939】【YNOI2016】掉进兔子洞(莫队)
    洛谷P3674 小清新人渣的本愿(莫队)
    Lucas卢卡斯定理
    组合数学习笔记
    洛谷P3178 [HAOI2015]树上操作(线段树)
    洛谷P3258 [JLOI2014]松鼠的新家(树上差分+树剖)
    洛谷P2526 [SHOI2001]小狗散步(二分图匹配)
    bzoj3140: [Hnoi2013]消毒(二分图)
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/9017368.html
Copyright © 2011-2022 走看看