USACO1.4 题解

Arithmetic Progressions

题意

让你求长为n的由小于2*m*m的双平方数组成的等差数列有几个

双平方数:形如 B=P*P+Q*Q,p,q>0的数


题解

枚举首项和公差,判n个数是否为等差数列,复杂度为m^4

m*m/(n-1)为公差的枚举次数,m*m为首项的结局次数,n为数列的枚举次数,其中还可以剪枝一下,如果数列的最后一项大于2*m*m,就break;

另一个优化是枚举前两个双平方数,算出首项公差,双平方的数量级是2e4,


代码

  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <set>
  6. #include<algorithm>
  7. #include<map>
  8. typedef long long ll;
  9. using namespace std;
  10. #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
  11. #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
  12. #define md(x) x=(x+mod)%mod
  13. #define pb push_back
  14. #define pii pair<int,int>
  15. #define x first
  16. #define y second
  17. int smain();
  18. #define ONLINE_JUDGE
  19. int main() {
  20. //ios::sync_with_stdio(false);
  21. #ifdef ONLINE_JUDGE
  22. FILE *myfile;
  23. myfile = freopen("ariprog.in", "r", stdin);
  24. if (myfile == NULL)
  25. fprintf(stdout, "error on input freopen\n");
  26. FILE *outfile;
  27. outfile = freopen("ariprog.out", "w", stdout);
  28. if (outfile == NULL)
  29. fprintf(stdout, "error on output freopen\n");
  30. #endif
  31. smain();
  32. return 0;
  33. }
  34. const int maxn = 13;
  35. #define FAST_IO ios_base::sync_with_stdio(false); cin.tie(nullptr)
  36. int n;
  37. int m;
  38. int cnt[130000];
  39. vector<pii> ans;
  40. vector<int> V;
  41. int smain() {
  42. FAST_IO;
  43. cin >> n>>m;
  44. rep(i, 0, m)rep(j, 0, m) {
  45. cnt[i*i + j * j]++;
  46. }
  47. int mm = m * m * 2;
  48. rep(i, 0, mm)if (cnt[i])V.push_back(i);
  49. int a, b;
  50. sort(V.begin(), V.end());
  51. rep(i, 0, V.size() - n+1) {
  52. rep(j, i+1, V.size() - n+1) {
  53. a = V[i]; b = V[j] - V[i];
  54. if (a + (n - 1)*b > mm)continue;
  55. //if (b <= 0)continue;
  56. int ok = 1;
  57. per(k,n-2,1) {
  58. int ai = V[j] + b * k;
  59. if (ai > mm) { ok = 0; break; }
  60. if(cnt[ai] == 0) { ok = 0; break; }
  61. }
  62. if (ok)ans.push_back({ b,a });
  63. }
  64. }
  65. sort(ans.begin(), ans.end());
  66. if(ans.empty())cout<<"NONE"<<endl;
  67. for (auto t : ans) {
  68. cout << t.y <<' '<< t.x << endl;
  69. }
  70. cin >> n;
  71. return 0;
  72. }

心路历程

  1. QAQ

Mother's Milk

题意

三个杯子的容量为a,b,c,每次选一个杯子X倒到另一个杯子Y里,直到Y倒不下或X倒空。问杯子c在杯子a为空的情况下水体积的所有可能的取值?


题解

状态只有20^3个,爆搜即可。

dfs的具体写法就是写六个状态转移,用123的全排列可以简化代码。

倒水的过程我封装了一下。


代码

  1. int n;
  2. int m;
  3. int a, b, c;
  4. set<int> ans;
  5. bool pour(int& x, int& y,int aa,int bb) {
  6. if (x==0||y == bb)return 0;
  7. if (x + y <= bb)y = x + y,x=0;
  8. else x = x + y - bb, y = bb;
  9. return 1;
  10. }
  11. void dfs(int x, int y, int z) {
  12. if (ans.count(x * 10000 + y * 100 + z))return;
  13. ans.insert(x * 10000 + y * 100 + z);
  14. int tx = x, ty = y, tz = z;
  15. if (pour(x, y, a, b))dfs(x, y, z); x = tx, y = ty;
  16. if (pour(y, x, b, a))dfs(x, y, z); x = tx, y = ty;
  17. if (pour(x, z, a, c))dfs(x, y, z); x = tx, z = tz;
  18. if (pour(z, x, c, a))dfs(x, y, z); x = tx, z = tz;
  19. if (pour(y, z, b, c))dfs(x, y, z); y = ty, z = tz;
  20. if (pour(z, y, c, b))dfs(x, y, z); y = ty, z = tz;
  21. }
  22. int main() {
  23. FAST_IO;
  24. cin >>a>>b>>c;
  25. int i = 1;
  26. int last = -1;
  27. dfs(0, 0, c);
  28. set<int> out;
  29. for (auto t : ans)if(t/10000==0)out.insert(t%100);
  30. for (auto t : out)cout << t << ' ';
  31. cout << endl;
  32. cin >> n;
  33. }

心路历程

  1. 一开始以为有什么技巧,想着用迭代加深来判dfs结束条件,结果想歪了。
  2. 其实所有状态搜完,dfs就结束了。

Prime Palindromes

题意

问区间(a,b)有哪些质数是回文数。


题解

判断一个1e8的质数,直接暴力即可。

如何生成回文数?我用了一个数组,用dfs生成前一半,然后在dfs底层对称一下,算出它对应的数。

数组可以用string代替,这样就可以reverse生成对称串了(其实数组也可以用reverse,不过string可以拼接)。

还有直接生成数字的递归写法。


代码

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<sstream>
  4. #include<stdlib.h>
  5. #include<string.h>
  6. #include<assert.h>
  7. #include<math.h>
  8. #include<stdio.h>
  9. #include<vector>
  10. #include<queue>
  11. #include<string>
  12. #include<ctime>
  13. #include<stack>
  14. #include<map>
  15. #include<set>
  16. #include<list>
  17. using namespace std;
  18. #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
  19. #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
  20. #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
  21. #define debug(x) cerr<<#x<<" = "<<(x)<<endl
  22. #define mmm(a,b) memset(a,b,sizeof(a))
  23. #define pb push_back
  24. #define MD(x) x%=mod
  25. #define FAST_IO ios_base::sync_with_stdio(false); cin.tie(nullptr)
  26. //#define pii pair<int,int>
  27. //#define x first
  28. //#define y second
  29. typedef double db;
  30. typedef long long ll;
  31. const int MAXN = 1e6;;
  32. const int maxn = 1e3 + 5;
  33. const int INF = 1e9;
  34. const db eps = 1e-7;
  35. const int mod = 1e9 + 7;
  36. int n;
  37. int N;
  38. //int ans;
  39. int num[10];
  40. int isp[10005];
  41. set<int> ans;
  42. int a, b;
  43. void sieveP() {
  44. rep(i, 1, 10000) {
  45. int ok = 1;
  46. for (int j = 2; j*j <= i; j++) {
  47. if (i%j == 0)ok = 0;
  48. }
  49. if (ok)isp[i] = 1;
  50. }
  51. }
  52. bool isprime(int x) {
  53. int ok = 1;
  54. for (int i = 2; i*i <= x;i++)if (isp[i]) {
  55. if (x%i == 0)ok = 0;
  56. }
  57. return ok;
  58. }
  59. void gene(int n) {
  60. if (n == 0) {
  61. if (N % 2) { rep(i, 0, 9) { num[N / 2 + 1] = i; gene(n - 1); } }
  62. else {
  63. rep(i, N / 2 + 1, N)num[i] = num[N + 1 - i];
  64. int val = 0;
  65. rep(i, 1, N)val*= 10, val += num[i];
  66. // cout << val << endl;
  67. if (val<=1e8&&isprime(val)&&val>=a&&val<=b)ans.insert(val);
  68. return;
  69. }
  70. }
  71. else if (n == -1) {
  72. rep(i, N / 2 + 2, N)num[i] = num[N + 1 - i];
  73. int val=0;
  74. rep(i, 1, N)val *= 10, val += num[i];
  75. //cout << val << endl;
  76. if (isprime(val) && val >= a && val <= b)ans.insert(val);
  77. return;
  78. }
  79. else rep(i, 0, 9) { num[n] = i; gene(n - 1); }
  80. }
  81. int main() {
  82. FAST_IO;
  83. sieveP();
  84. cin >> a >> b;
  85. int bita = 0;
  86. int bitb = 0,aa=a,bb=b;
  87. while (aa) { bita++; aa /= 10; }
  88. while (bb) { bitb++; bb /= 10; }
  89. for (N = bita; N <= bitb; N++) {
  90. gene(N / 2);
  91. }
  92. for (auto t : ans)cout << t << endl;
  93. cin >> n;
  94. return 0;
  95. }
  96. /*
  97. 5 100000000
  98. */

以下是三个标程:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <assert.h>
  4. #include <stdlib.h>
  5. FILE *fout;
  6. long a, b;
  7. int
  8. isprime(long n)
  9. {
  10. long i;
  11. if(n == 2)
  12. return 1;
  13. if(n%2 == 0)
  14. return 0;
  15. for(i=3; i*i <= n; i+=2)
  16. if(n%i == 0)
  17. return 0;
  18. return 1;
  19. }
  20. void
  21. gen(int i, int isodd)
  22. {
  23. char buf[30];
  24. char *p, *q;
  25. long n;
  26. sprintf(buf, "%d", i);
  27. p = buf+strlen(buf);
  28. q = p - isodd;
  29. while(q > buf)
  30. *p++ = *--q;
  31. *p = '\0';
  32. n = atol(buf);
  33. if(a <= n && n <= b && isprime(n))
  34. fprintf(fout, "%ld\n", n);
  35. }
  36. void
  37. genoddeven(int lo, int hi)
  38. {
  39. int i;
  40. for(i=lo; i<=hi; i++)
  41. gen(i, 1);
  42. for(i=lo; i<=hi; i++)
  43. gen(i, 0);
  44. }
  45. void
  46. generate(void)
  47. {
  48. genoddeven(1, 9);
  49. genoddeven(10, 99);
  50. genoddeven(100, 999);
  51. genoddeven(1000, 9999);
  52. }
  53. void
  54. main(void)
  55. {
  56. FILE *fin;
  57. fin = fopen("pprime.in", "r");
  58. fout = fopen("pprime.out", "w");
  59. assert(fin != NULL && fout != NULL);
  60. fscanf(fin, "%ld %ld", &a, &b);
  61. generate();
  62. exit (0);
  63. }
  1. //注意到偶数回文串必被11整除,所以生成奇数的即可
  2. #include <iostream.h>
  3. #include <fstream.h>
  4. #include <stdlib.h>
  5. int primelist[100000];
  6. int nprimes;
  7. int isPrime(int num);
  8. int reverse2(int i, int j);
  9. int compare(const void *p, const void *q) { return *(int *)p-*(int *)q; }
  10. void main (void) {
  11. ifstream infile("pprime.in");
  12. ofstream outfile("pprime.out");
  13. int i, j, begin, end, num;
  14. infile>>begin>>end;
  15. if (begin <= 11 && 11 <=end)
  16. primelist[nprimes++] = 11;
  17. for (j = 0; j <= 999; j++)
  18. for (i = 0; i <= 9; i++) {
  19. num = reverse2(j,i);
  20. if (num >= begin && num <=end && isPrime(num))
  21. primelist[nprimes++] = num;
  22. }
  23. qsort(primelist, nprimes, sizeof(int), compare);
  24. for (i = 0; i < nprimes; i++)
  25. outfile << primelist[i] << "\n";
  26. }
  27. int
  28. reverse2(int num, int middle) {
  29. int i, save=num, digit, combino = 1;
  30. for (i = 0; num; num /= 10) {
  31. digit = num % 10;
  32. i = 10 * i + digit;
  33. combino *= 10;
  34. }
  35. return i+10*combino*save+combino*middle;
  36. }
  37. int isPrime(int num) {
  38. int i;
  39. if (num <= 3) return 1;
  40. if (num%2 == 0 || num%3 ==0) return 0;
  41. for (i = 5; i*i <= num; i++)
  42. if (num %i ==0)
  43. return 0;
  44. return 1;
  45. }
  1. //递归不用数组
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. FILE *f;
  7. int a, b;
  8. int isPrime(int num);
  9. void genPalind(int num, int add, int mulleft, int mulright);
  10. void tryPalind(int num);
  11. int main(){
  12. int i;
  13. char first;
  14. f=fopen("pprime.in", "r");
  15. fscanf(f, "%d%d", &a, &b);
  16. fclose(f);
  17. f=fopen("pprime.out", "w");
  18. if (a<=5)
  19. fprintf(f, "%i\n", 5);
  20. if (a<=7 && b>=7)
  21. fprintf(f, "%i\n", 7);
  22. if (a<=11 && b>=11)
  23. fprintf(f, "%i\n", 11);
  24. genPalind(3, 0, 100, 1);
  25. genPalind(5, 0, 10000, 1);
  26. genPalind(7, 0, 1000000, 1);
  27. fclose(f);
  28. }
  29. void tryPalind(int num){
  30. if (!(num&1))
  31. return;
  32. if (num<a || num>b)
  33. return;
  34. if (!(num%3) || !(num%5) || !(num%7))
  35. return;
  36. if (!isPrime(num))
  37. return;
  38. fprintf(f, "%d\n", num);
  39. }
  40. void genPalind(int num, int add, int mulleft, int mulright){
  41. int i, nmulleft, nmulright;
  42. if (num==2){
  43. for (i=0; i<10; i++)
  44. tryPalind(add+mulleft*i+mulright*i);
  45. }
  46. else if (num==1){
  47. for (i=0; i<10; i++)
  48. tryPalind(add+mulright*i);
  49. }
  50. else {
  51. nmulleft=mulleft/10;
  52. nmulright=mulright*10;
  53. num-=2;
  54. for (i=0; i<10; i++)
  55. genPalind(num, add+i*mulleft+i*mulright, nmulleft, nmulright);
  56. }
  57. }
  58. int isPrime(int num){
  59. int koren, i;
  60. koren=(int)sqrt(1.0*num);
  61. for (i=11; i<=koren; i+=2)
  62. if (!(num%i))
  63. return 0;
  64. return 1;
  65. }

心路历程

  1. 一开始打算写最后的那个标程,不会啊QAQ orz%%%

Superprime Rib

题意

输出所有n位的super prime.

super prime: 如果质数X,有X/10,X/100,X/1000...都是质数,那么它就是sprime


题解

上一题简化版,直接从第一个数字不断往后dfs,每层都是质数,所以剪枝性很强。


代码

  1. //头文件省略
  2. int n;
  3. int N;
  4. //int ans;
  5. int num[10];
  6. int isp[10005];
  7. set<int> ans;
  8. int a, b;
  9. void sieveP() {
  10. rep(i, 1, 10000) {
  11. int ok = 1;
  12. for (int j = 2; j*j <= i; j++) {
  13. if (i%j == 0)ok = 0;
  14. }
  15. if (ok)isp[i] = 1;
  16. }
  17. }
  18. bool isprime(int x) {
  19. if(x==1)return 0;
  20. int ok = 1;
  21. for (int i = 2; i*i <= x;i++)if (isp[i]) {
  22. if (x%i == 0)ok = 0;
  23. }
  24. return ok;
  25. }
  26. void gene(int n,int num) {
  27. if (n == 0) { if(num/N)cout << num<<endl; return; }
  28. rep(i, 0, 9) {
  29. if (isprime(num * 10 + i))gene(n - 1, num * 10 + i);
  30. }
  31. }
  32. int smain() {
  33. FAST_IO;
  34. sieveP();
  35. cin >> n;
  36. N = pow(10, n - 1);
  37. gene(n,0);
  38. cin >> n;
  39. return 0;
  40. }

心路历程



USACO1.4 1.5 搜索剪枝与数字 洛谷OJ P1214 P1215 P1217 P1218的更多相关文章

  1. AC日记——[USACO1.1]坏掉的项链Broken Necklace 洛谷 P1203

    题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 n=29 的二个例子: 第一和第二个珠子在图片中已经被作记号. 图片 A ...

  2. 【洛谷4005】小Y和地铁(搜索)

    [洛谷4005]小Y和地铁(搜索) 题面 洛谷 有点长. 题解 首先对于需要被链接的两个点,样例中间基本上把所有的情况都给出来了. 但是还缺了一种从下面绕道左边在从整个上面跨过去在从右边绕到下面来的情 ...

  3. [luogu 1092] 虫食算 (暴力搜索剪枝)

    传送门 Description Input 包含四行. 第一行有一个正整数 (N≤26). 后面的三行,每行有一个由大写字母组成的字符串,分别代表两个加数以及和.这3个字符串左右两端都没有空格,从高位 ...

  4. NOIP2015 斗地主(搜索+剪枝)

    4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 270  Solved: 192[Submit][Status] ...

  5. hdu 5469 Antonidas(树的分治+字符串hashOR搜索+剪枝)

    题目链接:hdu 5469 Antonidas 题意: 给你一颗树,每个节点有一个字符,现在给你一个字符串S,问你是否能在树上找到两个节点u,v,使得u到v的最短路径构成的字符串恰好为S. 题解: 这 ...

  6. hdu 5887 搜索+剪枝

    Herbs Gathering Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  7. hdu 5113(2014北京—搜索+剪枝)

    题意:有N*M的棋盘,用K种颜色去染,要求相邻块不能同色.已知每种颜色要染的块数,问能不能染,如果能,输出任一种染法. 最开始dfs失败了- -,优先搜索一行,搜完后进入下一列,超时.本来以为搜索不行 ...

  8. luogu 1731 搜索剪枝好题

    搜索剪枝这个东西真的是骗分利器,然鹅我这方面菜的不行,所以搜索数学dp三方面是真的应该好好训练一下 一本通的确该认真的刷嗯 #include<bits/stdc++.h> using na ...

  9. 搜索+剪枝——POJ 1011 Sticks

    搜索+剪枝--POJ 1011 Sticks 博客分类: 算法 非常经典的搜索题目,第一次做还是暑假集训的时候,前天又把它翻了出来 本来是想找点手感的,不想在原先思路的基础上,竟把它做出来了而且还是0 ...

随机推荐

  1. 爬虫时遇到的' 编码错误gbk ' 的解决方案

    # 每次请求一次,然后写文件,这样可以规避多次请求触发反爬虫 r = requests.get('https://www.pearvideo.com/video_1522192') html = r. ...

  2. laravel5.4 向闭合函数内部传递参数

    laravel  向闭合函数内部传入参数

  3. C++设计模式——观察者模式

    观察者模式 在GOF的<设计模式:可复用面向对象软件的基础>一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动 ...

  4. 递归遍历所有xml的节点及子节点

    import java.io.File; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; i ...

  5. Thymleaf js直接获取后台传过来的对象或者对象的属性以及map

    简单说明:第一次接触thymleaf模板,对于thymleaf在js中如何获取后台传递过来的值,真的挺简单的,记住就行了 代码: 后台代码: //传递一个org对象给jspublic String t ...

  6. 记账本-NABCD分析

    N(Need)需求 这个软件主要解决了大学生管理自己财务状况的问题,随着手机支付的日趋流行大家对财务的概念就变成了银行卡账户余额的一串数字,在不知不觉中,这串数字就一变小,也就出现了月光族.由此看来, ...

  7. selenium+python-unittest多线程生成报告

    前言 selenium多线程跑用例,这个前面一篇已经解决了,如何生成一个测试报告这个是难点,刚好在github上有个大神分享了BeautifulReport,完美的结合起来,就能生成报告了. 环境必备 ...

  8. 论文阅读笔记四十五:Region Proposal by Guided Anchoring(CVPR2019)

    论文原址:https://arxiv.org/abs/1901.03278 github:code will be available 摘要 区域anchor是现阶段目标检测方法的重要基石.大多数好的 ...

  9. pta编程总结3

    7-1 抓老鼠啊~亏了还是赚了? (20 分) 某地老鼠成灾,现悬赏抓老鼠,每抓到一只奖励10元,于是开始跟老鼠斗智斗勇:每天在墙角可选择以下三个操作:放置一个带有一块奶酪的捕鼠夹(T),或者放置一块 ...

  10. ReactiveCocoa - study

    //KVO值监控,当alertTip改变时调用, filter对alertTip值进行过滤,此处当alertTip存在而长度不为0时,执行suscribeNext方法,弹出提示 [[RACObserv ...