14级寒假集训————数论基础
来源:互联网 发布:网络统考成绩查询时间 编辑:程序博客网 时间:2024/06/06 13:01
题目链接:点击打开链接
A.
题目大意:
对自然数进行重新排列,排列规则如下:首先排列从1到n的奇数(升序),然后排列从1到n的偶数(升序)。输出这样排列后的第k个数。
解题思路:
首先分析,当n为偶数时,num(奇) == num(偶);当n为奇数时,num(奇) + 1 == num(偶)
。
接下来我们以(n + 1) / 2为分界线,把前面的num(奇)和后面的num(偶)分开。如果k小于等于(n+1) / 2,那么一定在奇数范围内,分析规律得出第k个数为k * 2 – 1;如果k大于(n+1) / 2,那么一定在偶数范围内,分析规律得出第k个数为(k – (n + 1) / 2 ) * 2。
完整代码:
#include <iostream>#include <cstdio>using namespace std;__int64 n , k;void solve(){ printf("%I64d\n" , k <= (n + 1) / 2 ? k * 2 - 1 : (k - (n + 1) / 2) * 2);}int main(){ #ifdef DoubleQ freopen("in.txt","r",stdin); #endif while(~scanf("%I64d%I64d" , &n , &k)) solve(); return 0;}
B.
题目大意:
一个山丘周围有逆时针标号为0到n-1的洞,兔子躲在某个洞中。狼从标号0开始,沿逆时针方向追赶兔子。规则如下:例如m=2,n=6,狼进过洞的标号依次为0、2、4、0。如果兔子隐藏在标号为1、3、5的洞内,就不会被狼吃掉,我们称这样的洞为safe holes。
对于每组m和n,如果存在safe holes,输出YES,否则输出NO。
解题思路:
首先一定会想到如果m和n都是偶数或者m和n之间存在不为1的倍数关系,那么一定存在safe holes使得狼无法到达;
再想一想,如果gcd( m , n) == 1,那么一定不会存在safe holes,狼会找遍所有的洞,最终吃掉兔子。
完整代码:
#include <cstdio>#include <iostream>using namespace std;int gcd(int a , int b){ return b == 0 ? a : gcd(b , a % b);}void solve(){ int n , m; scanf("%d%d",&n,&m); printf("%s\n" , gcd(n , m) != 1 ? "YES" : "NO");}int main(){ #ifdef DoubleQ freopen("in.txt","r",stdin); #endif int T; scanf("%d",&T); while(T--) solve(); return 0;}
C.
题目大意:
哥德巴赫猜想说:“每个不小于4的偶数可以表示成两个素数之和。”让我们定义一个新的猜想:“每个不小于12的整数可以表示成两个合数的和。”
解题思路:
首先会想到从4到n遍历,如果i 和 n – i 都是合数,那么输出即可。
再想一想,可以用素数筛法进行打表,把100000内的素数标记为true,合数标记为false。从4到n遍历,如果pri[ i ] 和pri[ n – i ]都是合数的话,输出即可。
附上另外一种思路:如果n是偶数,那么输出4和n-4即可,因为4是最小的合数,n-4也必为偶数(n >12);如果n是奇数,那么输出9和n - 9即可,因为9是合数里最小的奇数,n - 9必为偶数。
完整代码:
朴素方法
#include <iostream>#include <cstdio>#include <cmath>using namespace std;int n;bool is(int key){ int m = sqrt(key); for(int i = 2 ; i <= m ; i ++) if(key % i == 0) return true; return false;}void solve(){ for(int i = 4 ; i <= n ; i ++) if(is(i) && is(n - i)) { printf("%d %d\n", i , n - i); return; }}int main(){ #ifdef DoubleQ freopen("in.txt","r",stdin); #endif while(~scanf("%d",&n)) solve(); return 0;}
打表筛法
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>using namespace std;int n;const int maxn = 1000001;bool pri[maxn];void is(){ memset(pri , true , sizeof(pri)); pri[0] = pri[1] = false; int m = sqrt(maxn); for(int i = 2 ; i <= m ; i ++) { if(pri[i]) { for(int j = i * i ; j < maxn ; j += i) pri[j] = false; } }}void solve(){ for(int i = 4 ; i <= n ; i ++) if(!pri[i] && !pri[n - i]) { printf("%d %d\n", i , n - i); return; }}int main(){ #ifdef DoubleQ freopen("in.txt","r",stdin); #endif is(); while(~scanf("%d",&n)) solve(); return 0;}
另外一种解法
#include <iostream>#include <cstdio>using namespace std;int n;int main(){while(~scanf("%d", &n)) { if(n%2==0) printf("4 %d\n", n - 4); else printf("9 %d\n", n - 9); }return 0;}
题目大意:
100层的电梯,电梯显示器会显示两位数字(不满两位高位用0替代),代表当前层数。但是由于机器故障,显示器的某些灯没有亮。给你当前显示器的数字n,问它有多少种可能的层数。
解题思路:
可以把显示器的灯想象成火柴棍,对于当前数字,通过增添火柴棍,使其构成另外一个数字。设n的十位为a,个位为b。a通过增添火柴棍所能构成Pa个数字,b通过增添火柴棍所能构成Pb个火柴棍。那么Pa * Pb即为所求。
0可以构成0和8;
1可以构成1、7、3、4、8、9、0;
2可以构成2、8;
3可以构成3、9、8;
4可以构成4、9、8;
5可以构成5、6、8、9;
6可以构成6、8;
7可以构成7、3、9、0、8;
8只可以构成8;
9可以构成9、8。
完整代码:
#include <iostream>#include <cstdio>using namespace std;int n;int a[] = {2 , 7 , 2 , 3 , 3 , 4 , 2 , 5 , 1 , 2};void solve(){ printf("%d\n" , a[n % 10] * a[n / 10]);}int main(){ #ifdef DoubleQ freopen("in.txt","r",stdin); #endif while(~scanf("%d",&n)) solve(); return 0;}
E.
题目大意:
略
解题思路:
预处理出前1000个斐波那契数,编写高精度加法函数,最后实现O(1)时间的查找。论C++和JAVA写高精度的代码量。
完整代码:
C++版
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1001;string f[maxn];string add(string a , string b){ int lena = a.length(); int lenb = b.length(); int maxlen = max(lena , lenb); int minlen = min(lena , lenb); string maxx = lena >= lenb ? a : b; string minn = lena < lenb ? a : b; string result = ""; reverse(maxx.begin() , maxx.end()); reverse(minn.begin() , minn.end()); int k = 0; int key; for(int i = 0 ; i < minlen ; i ++) { key = (maxx[i] - '0') + (minn[i] - '0') + k; if(key > 9) { k = key / 10; key -= k * 10; } else k = 0; result += (char)(key + '0'); } for(int i = minlen ; i < maxlen ; i ++) { key = (maxx[i] - '0') + k; if(key > 9) { k = key / 10; key -= k * 10; } else k = 0; result += (char)(key + '0'); } if(k) result += (char)(k + '0'); reverse(result.begin() , result.end()); return result;}void fib(){ f[1] = f[2] = "1"; for(int i = 3 ; i < maxn ; i ++) f[i] = add(f[i-1] , f[i-2]);}void solve(){ int n; scanf("%d",&n); cout << f[n] << endl;}int main(){ #ifdef DoubleQ freopen("in.txt" , "r" , stdin); #endif; int T; scanf("%d",&T); fib(); while(T--) solve(); return 0;}
JAVA版
import java.math.*; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin = new Scanner(System.in); BigInteger m[] = new BigInteger[1001]; BigInteger start = new BigInteger("1"); m[1] = start; m[2] = start; for(int i = 3 ; i < 1001 ; i ++){ m[i] = m[i-1].add(m[i-2]); } int n = cin.nextInt(); while(n != 0){ int key = cin.nextInt(); System.out.println(m[key]); n--; } } }
F.
题目大意:
给一个长度为n的整数序列a[0],a[1],•••,a[n - 1],找出两个整数a[ i ]和a[ j ] (i < j),使得a[i] – a[j]尽量大。
解题思路:
首先会想到O(n^2)的暴力解法,很可惜这样做一定会超时,因为n达到10^5.
这道题O(n)时间内可解。对于每一个固定的j,我们应选择的是小于j且a[ i ]最大的i ,而和a[ j ]的具体值无关。我们从小到大枚举j , 顺便维护a[ i ]的最大值即可。
完整代码:
#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1000001;int a[maxn];void solve(){ int n; scanf("%d",&n); for(int i = 0 ; i < n ; i ++) scanf("%d",&a[i]); int maxi = a[0]; int maxx = a[0] - a[1]; for(int i = 1 ; i < n ; i ++) { maxi - a[i] > maxx ? maxx = maxi - a[i] : maxx = maxx; a[i] > maxi ? maxi = a[i] : maxx = maxx; } printf("%d\n",maxx);}int main(){#ifdef DoubleQ freopen("in.txt","r",stdin);#endif int T; scanf("%d",&T); while(T--) solve(); return 0;}
- 14级寒假集训————数论基础
- 寒假集训——KMP
- 寒假集训——AreYouBusy
- 寒假集训——饭卡
- 寒假集训第四天——排序
- 寒假集训——二叉树
- 寒假集训——Find Metal Mineral
- 寒假集训——Gift Hunting
- 寒假集训——The Fewest Coins
- 2017.1.14——寒假集训第三天
- 2016寒假训练——数论
- 寒假集训作业(1)——结构体
- 寒假集训作业(2)——链表
- 寒假集训作业(3)——栈与队列
- 寒假集训作业(4)——字符串
- 寒假集训作业(6)——动态规划初步
- 寒假集训作业(7)——排序查找
- 寒假集训作业(8)——数学问题
- Struts2.3.20使用token防表单重复提交:警告: Could not find token name in params.
- python中os.chdir()和from...import应用中的错误
- 一个C的小游戏
- Android中AIDL使用例子
- Core Foundation与Foundation
- 14级寒假集训————数论基础
- C#之Socket编程进阶
- Objective - C基础: 第一天 - 7.第二个OC类练习
- Http与Https的区别
- A Tour of Machine Learning Algorithms
- MONGODB基本命令用
- mysql数据库修改用户密码
- 基础算法之排序(2)--简单选择排序
- Android 的,开源还是不开源?