zoukankan      html  css  js  c++  java
  • 1001考试

    1001考试总结

    T1

    ​ 题目大意:

    ​ 石子一共有n堆,其中第i堆恰好有i粒石子。小林先取,亮亮后取,并且两人依次轮流取石。每一次取石子的人可以选择任意一堆还未被取完的石子,并取走这一堆中任意多粒石子(注意,不能一粒石子也不取,也不能同时在多堆石子中取石)。最终,无石可取的人为败。小林和亮亮都十分聪明,他们的每次取石都会采取最优策略。在经过多次游戏后,小林发现了先手必胜的条件,但他不满足于此,他想知道,在知道石子的堆数n后,他第一次取石有多少种方式可以获胜。

    博弈论早忘了,不过正解好像是找规律233333

    ​ 首先我们得知道一个规律:

    S表示1~n的异或和:
        n % 4 == 0, s = n;
        n % 4 == 1, s = 1;
        n % 4 == 2, s = n + 1;
        n % 4 == 3, s = 0;
    

    ​ 最简单的证明:打标找规律。不过网上还是有证明的,我不会。

    ​ 当(n \% 4 == 3)时,输出0,因为先手必输。最简单的nim游戏。

    ​ 当(n \% 4 == 1)时,我们对任意一个奇数堆进行操作都可以使异或和变为0,答案为((n + 1) / 2)

    ​ 剩下那两种情况,S与n位数相同。设它们的最高位为t,S的第t位为1,为使S变为0,必须修改一个第t位为1的数。显然修改任一第t位为1的数都可以使S变为0。答案即为n去掉最高位再加1。(题解原话)

    ​ 这是90分代码,最后10分打高精,不想写了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
    	long long s = 0, f = 1; char ch;
    	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
    	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
    	return s * f;
    }
    
    const int N = 5005;
    int T;
    long long n;
    int SG[N];
    
    int main() {
    	
    	freopen("nim.in","r",stdin); freopen("nim.out","w",stdout);
    	
    	T = read();
    	while(T --> 0) {
    		n = read();
    		if(n % 4 == 3) printf("0
    ");
    		if(n % 4 == 1) printf("%lld
    ", (n + 1) / 2);
    		if(n % 4 == 2 || n % 4 == 0) {
    			long long y = 1, x = n;
    			while(y <= x) y *= 2;
    			y /= 2; x -= y; x++;
    			printf("%lld
    ", x);
    		}
    	}
    	
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    

    T2

    ​ 题目大意:

    ​ 小林和亮亮是好朋友。小林有一个幸运数字a,亮亮有一个幸运数字b。一个数字称之为“幸运数”当且仅当它只由a和b组成。小林称一个数为“魔数”,当且仅当这个数各数位之和为“幸运数”,且这个数字本身也是“幸运数”。举个例子:小林的幸运数字为2,亮亮的幸运数字为6,那么23不是“幸运数”,而26、222是“幸运数”。进一步,222是“魔数”(因为2+2+2=6),而26不是“魔数”(因为2+6=8)。亮亮想要知道,有多少个n位的“魔数”(一个n位数不包含前导0),由于这个数字会很大,所以亮亮只关心这个数模1000000007(10^9+7,是一个质数)的结果。

    ​ 这个题还挺简单的,机房好多人都切了。

    ​ 直接枚举a的个数,那么b的个数也相应的出来了,然后判断这个数的和是否是幸运数,如果是的话给答案加上(C_{n}^{i})

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
    	long long s = 0, f = 1; char ch;
    	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
    	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
    	return s * f;
    }
    
    const int N = 1e6 + 5, mod = 1e9 + 7;
    int a, b, n, ans;
    int fac[N], inv[N];
    
    int calc(long long x) {
    	while(x) {
    		int tmp = x % 10; x /= 10;
    		if(!(tmp == a || tmp == b)) return 0;
    	}
    	return 1;
    }
    
    void make_pre() {
    	fac[0] = fac[1] = inv[0] = inv[1] = 1;
    	for(int i = 2;i <= N - 5; i++) fac[i] = 1ll * fac[i - 1] * i % mod;
    	for(int i = 2;i <= N - 5; i++) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
    	for(int i = 2;i <= N - 5; i++) inv[i] = 1ll * inv[i - 1] * inv[i] % mod; 
    }
    
    int C(int x, int y) {
    	if(x < y) return 0;
    	return 1ll * fac[x] * inv[y] % mod * inv[x - y] % mod; 
    }
    
    int main() {
    	
    	freopen("number.in","r",stdin); freopen("number.out","w",stdout);
    	
    	a = read(); b = read(); n = read(); make_pre();
    	for(int i = 0;i <= n; i++) 
    		if(calc(1ll * a * i + 1ll * b * (n - i))) ans = (ans + C(n, i)) % mod;
    	printf("%d", ans);
    	
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    

    T3

    ​ 题目大意:

    ​ 小林和亮亮刚入高中,首先就迎来了军训。这一天,他们班的同学正在教官的指导下进行队列练习。班上总共有n位同学,他们站成一排,然而,本该站成一条直线的他们却排成了“一字长蛇阵”。用数学的语言来描述,如果把训练场看成一个平面直角坐标系,第i名同学所在位置的横坐标是i,而所有同学的纵坐标本该是0(或者任意一个相等的常量),这样就排成了一条直线。当然,由于同学们排的歪歪扭扭,所以第i位同学的横坐标依然是i,而纵坐标却成了iY(为了简化问题,我们假设所有的坐标都是整数)。对此,教官当然十分生气,因此他决定下命令调整队伍,使得所有人能够站成一条直线(也即让所有的iY相同)。教官的命令总共有三种:1、除了某一个同学外,其余所有同学向前走一步(向前走一步可理解为iY的值加1,下同);2、除了某一个同学外,其余所有同学向前走两步;3、除了某一个同学外,其余所有同学向前走五步。教官希望他能以最少的命令次数使得所有同学站成一条直线,但是他不会算,于是就让亮亮帮他来计算。亮亮虽然聪明,可是由于班上同学人数众多,他一下子也解决不了这个问题,只能来寻求会编程的你的帮助,你能告诉亮亮答案吗?

    ​ 乱搞吧。

    ​ 我们先按高度排个序,现在我们枚举到了(a[i]),想让(a[i - 1])与它的高度相同,我们搞一个指令:让处理(i)这个位置其他位置都走(y)步,假设与(a[i])等高的有(x)个,那么所有(a[i])高度的应该是往前走了((x - 1) *y)步,所有(a[i - 1])高度的应该是走了(x * y)步。

    ​ 现在我们的到来一个等式:(a[i] +(x - 1) * y = a[i - 1] + x * y),化简一下:(y = a[i] - a[i - 1])。这样我们就可以知道应该走多少步可以使高度为(a[i], a[i - 1])相同了。注意记录一个(last),表示之前就已经加过多少高度了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
    	long long s = 0, f = 1; char ch;
    	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
    	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
    	return s * f;
    }
    
    const int N = 1e5 + 5;
    int n, cnt, a[N];
    long long ans, last;
    struct que { int x, h; } b[N];
    
    long long calc(long long x) {
    	long long res = 0;
    	long long x1 = x / 5, x2 = x % 5;
    	res += x1;
    	if(x2 != 0) {
    		x = x % 5;
    		x1 = x / 2; x2 = x % 2;
    		res += x1 + x2;
    	}
    	return res;
    }
    
    int main() {
    	
    	freopen("queue.in","r",stdin); freopen("queue.out","w",stdout);
    	
    	n = read();
    	for(int i = 1;i <= n; i++) a[i] = read();
    	sort(a + 1, a + n + 1);
    	a[0] = -1; //一定注意这里,不然有0的情况会错!!!
    	for(int i = 1;i <= n; i++)
    		if(a[i] != a[i - 1]) b[++cnt].h = a[i], b[cnt].x = 1;
    		else b[cnt].x ++;
    	for(int i = 2;i <= cnt; i++) {
    		long long der = b[i].h - b[i - 1].h + last;
    		ans += 1ll * b[i].x * calc(der); last = der;
    	}
    	
    	printf("%lld", ans);
    	
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    /*
    4
    1 1 2 6
    2
    
    6
    1 1 2 2 6 8
    5
    
    8
    1 3 3 5 5 5 7 7 
    12
    
    8
    1 2 4 6 2 5 4 5
    11
    
    9
    5 6 1 5 5 2 2 1 5 
    11
    
    8
    9 6 8 9 6 8 5 4
    9
    */
    
    

    总结

    ​ 期望0 + 100 +100 = 200pts,实得0 +100 + 90 = 190pts。预期挺准的吧。

    ​ 其实第一题那种题可以打个表找找规律的,别懒得打。

    ​ 多考虑考虑细节,第三题那10分不该丢。

    ​ %%%机房里290大佬。

  • 相关阅读:
    [ZJOI2007]时态同步 题解
    Xposed 在android 6.0上报couldn't load class,找不到xposed_init中配置的入口类
    微信小程序http 400问题
    在Mac上 python中使用tesseract OCR (Pytesser) 识别图片中的文字
    微信小游戏跳一跳简单手动外挂(基于adb 和 python)
    第一个微信小程序踩的几个小坑
    android studio/Intellij IDEA(MAC OSX)中android模拟器无法启动的一种原因
    【转载】word2vec原理推导与代码分析
    HTTP Get Post究竟有哪些区别
    初试kotlin:用Kotlin开发桌面/CommandLine 工具
  • 原文地址:https://www.cnblogs.com/czhui666/p/13759213.html
Copyright © 2011-2022 走看看