【题解】SWJTU2015.12校队选拔题解

今年上半学期的校队选拔题目,是从poj上抽的几道题。为了照顾尚未学习算法和数据结构的同学,同时结合前几次培训的内容,考察了模拟,搜索和数学题目,总体来说,题目没有太大的难度,但两道搜索较为繁杂,需要考虑一些细节问题,同时也要求良好的编写代码能力。编写代码能力是ACM学习的基础,希望各位同学能多花时间写一写题,加强编写代码的能力。若对题解有疑问,可在下方评论或直接与我联系。

【POJ2739】Sum of Consecutive Prime Numbers

对给定的一个数k,寻找可以被连续素数之和组成的方案数,由于在[1,10000]区间内的素数只有小于1300个,可以直接用素数筛找出所有素数后,通过枚举所有方案,得到答案。

#include<iostream>
#include<cstdio>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
const int maxn = 10000;
int prime[maxn + 10],m = 0;
int cou[maxn + 10];
bool vis[maxn + 10];
int init() {
    for (int i = 2;i <= maxn; i++)
        if (!vis[i]) {
            prime[++m] = i + prime[m-1];
            for (int j = i+i;j <= maxn; j += i) vis[j] = true;
        }
    for (int i = 1;i <= m; i++)
        for (int j = i-1;j >= 0; j--)
            if (prime[i]-prime[j] <= maxn) cou[prime[i]-prime[j]]++;
            else break;
}
int main() {
    init();
    int n;
    while (scanf("%d",&n) != EOF) {
        if (!n) break;
        printf("%d\n",cou[n]);
    }
	return 0;
}


【POJ1573】Robot Motion

模拟题,求机器人在题中给出地图中行走的步数,根据题目中给定的规则执行即可,注意字符的读取。


#include<iostream>
#include<cstdio>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
const int mov[4][2] = {-1,0,1,0,0,1,0,-1};
int n,m,k;
char a[1010][1010];
int vis[1010][1010];
map<char,int> dir;
bool is_sta(int x,int y) {
    if (x < 1 || x > n || y < 1 || y > m) return false;
    return true;
}
int main() {
    dir['N'] = 0;dir['S'] = 1;dir['E'] = 2;dir['W'] = 3;
    while (scanf("%d%d%d%*c",&n,&m,&k) != EOF) {
        memset(vis,0,sizeof(vis));
        if (n == 0 && m == 0 && k == 0) break;
        for (int i = 1;i <= n; i++) {
            for (int j = 1;j <= m; j++) scanf("%c",&a[i][j]);
            scanf("%*c");
        }
        int x = 1,y = k,cou = 1;
        int s1 = 0,s2 = 0;
        vis[x][y] = 1;
        while (true) {
            int d = dir[a[x][y]];
            x += mov[d][0];
            y += mov[d][1];
            //cout << x <<":" << y << endl;
            if (!is_sta(x,y)) {
                s1 = cou;
                break;
            }
            if (vis[x][y]) {
                s1 = vis[x][y] - 1;
                s2 = cou - vis[x][y] + 1;
                break;
            }
            vis[x][y] = ++cou;
        }
        if (s2) printf("%d step(s) before a loop of %d step(s)\n",s1,s2);
        else printf("%d step(s) to exit\n",s1);
    }
	return 0;
}


【POJ2109】Power of Cryptography

给出n,p,求使k^n = p的k,之前我做这道是用对数做的,后来发现直接开方就可以OTZ,所以其实这才是最水的一道题。


#include<iostream>
#include<cstdio>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
int main() {
    double n,p;
    while (scanf("%lf%lf",&n,&p) != EOF) {
        double k = log2(p)/n;
        int ans = pow(2,k) + eps;
        //像这样也可以过OTZ
        // int ans = (double)pow(p,1/n) + eps; 
        printf("%d\n",ans);
    }
	return 0;
}


【POJ3009】Power of Cryptography

DFS深度优先搜索,因为数据范围很小,不用加优化也可以通过,枚举每次滚动的方向进行搜索。值得注意的一点:本题中是先给列数,再给的行数。


#include<iostream>
#include<cstdio>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
const int mov[4][2] = {1,0,-1,0,0,1,0,-1};
int n,m,ans;
int a[30][30];
bool is_sta(int x,int y) {
    if (x < 1 || x > n || y < 1 || y > m) return false;
    return true;
}
void dfs(int x,int y,int step) {
    if (step > 10) return;
    for (int i = 0;i < 4; i++) {
        if (a[x+mov[i][0]][y+mov[i][1]] == 1) continue;
        int nx = x,ny = y;
        while (is_sta(nx,ny) && a[nx][ny] != 3 && a[nx][ny] != 1) {
            nx += mov[i][0];
            ny += mov[i][1];
        }
        if (!is_sta(nx,ny)) continue;
        if (a[nx][ny] == 3) {
            if (ans == -1) ans = step;
            else ans = min(ans,step);
        }
        if (a[nx][ny] == 1) {
            a[nx][ny] = 0;
            dfs(nx-mov[i][0],ny-mov[i][1],step+1);
            a[nx][ny] = 1;
        }
    }
}
int main() {
    while (scanf("%d%d",&m,&n) != EOF) {
        memset(a,0,sizeof(a));
        if (n == 0 && m == 0) break;
        int x,y;
        for (int i = 1;i <= n; i++)
            for (int j = 1;j <= m; j++) {
                scanf("%d",&a[i][j]);
                if (a[i][j] == 2) {x = i;y = j;}
            }
        ans = -1;
        dfs(x,y,1);
        printf("%d\n",ans);
    }
	return 0;
}


【POJ3414】Pots

BFS宽度优先搜索,可视为无权图最短路问题,用BFS解决,在每轮中枚举六种操作,第一次找到的解即为最优解,之后递归输出方案。


#include<iostream>
#include<cstdio>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
struct point {
    int x,y,f,act;
};
point line[10100];
bool vis[110][110];
void print(int k,int cnt) {
    if (line[k].f) print(line[k].f,cnt+1);
    else printf("%d\n",cnt);
        if (line[k].act == 1) puts("FILL(1)");
        if (line[k].act == 2) puts("FILL(2)");
        if (line[k].act == 3) puts("DROP(1)");
        if (line[k].act == 4) puts("DROP(2)");
        if (line[k].act == 5) puts("POUR(1,2)");
        if (line[k].act == 6) puts("POUR(2,1)");

}
int main() {
    int a,b,c;
    while (scanf("%d%d%d",&a,&b,&c) != EOF) {
        memset(vis,0,sizeof(vis));
        int p1 = 1,p2 = 1;
        line[p2++] = (point){0,0,0};
        vis[0][0] = true;
        bool ans = false;
        while (p1 < p2) {
            point p = line[p1];
            if (p.x == c || p.y == c) {
                print(p1,0);
                ans = true;
                break;
            }
            if (!vis[a][p.y]) {
                line[p2++] = (point){a,p.y,p1,1};
                vis[a][p.y] = true;
            }
            if (!vis[p.x][b]) {
                line[p2++] = (point){p.x,b,p1,2};
                vis[p.x][b] = true;
            }
            if (!vis[0][p.y]) {
                line[p2++] = (point){0,p.y,p1,3};
                vis[0][p.y] = true;
            }
            if (!vis[p.x][0]) {
                line[p2++] = (point){p.x,0,p1,4};
                vis[p.x][0] = true;
            }
            int x = p.x,y = p.y;
            if (p.x + p.y > b) x = p.x+p.y-b,y = b;
            else x = 0,y = p.x+p.y;
            if (!vis[x][y]) {
                line[p2++] = (point){x,y,p1,5};
                vis[x][y] = true;
            }
            x = p.x,y = p.y;
            if (p.x + p.y > a) x = a,y = p.x+p.y-a;
            else x = p.x+p.y,y = 0;
            if (!vis[x][y]) {
                line[p2++] = (point){x,y,p1,6};
                vis[x][y] = true;
            }
            p1++;
        }
        if (!ans) puts("impossible");
    }
	return 0;
}


【POJ1850】Code

递推,计算给出的字符串是第几个递增字符串,f[i][j]表示最高位是第i位,第i位为j(0 <= j < 26)的递增字符串个数,递推式为

f[i][j] = sum(f[i-1][k](1 <= k < 26))(j = 0)

f[i][j] = f[i][j-1] - f[i][j] (0 < j < 26)


#include<iostream>
#include<cstdio>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
string st;
int f[20][30];
void init() {
    for (int i = 0;i < 26; i++) f[1][i] = 1;
    for (int i = 2;i <= 10; i++) {
        for (int j = 1;j < 26; j++) f[i][0] += f[i-1][j];
        for (int j = 1;j <= 26-i; j++) f[i][j] = f[i][j-1] - f[i-1][j];
    }
}
int main() {
    init();
    while (cin >> st) {
        int ans = 0,n = st.length();
        for (int i = 1;i < n; i++) {
            if (st[i] < st[i-1]) {
                ans = -1;
                break;
            }
        }
        if (ans == -1) {
            printf("%d\n",0);
            break;
        }
        for (int i = n;i > 0; i--) {
            for (int j = 0;j <= st[n-i]-'a'; j++) ans += f[i][j];
        }
        printf("%d\n",ans);
    }
	return 0;
}


到此,本学期与ACM有关的活动已经全部结束,回顾月赛,新秀杯和这次的选拔赛,不知道大家在ACM中收获了什么?如果能在coding感受到快乐的话,那是再好不过了。时间已经临近期末,也请大家好好复习,祝大家在期末考试中能取得好成绩!另外,校集训队会在寒假中组织培训,主要内容为动态规划(DP)及图论算法。

我们寒假再见!

PS:天气太冷我已经冻感冒了,大家也注意身体(吸鼻涕,总之早点睡觉多喝热水总是没错的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
《计算机操作系统(第4版)》学习指导与题解 含实验.pdf是一本关于计算机操作系统的学习指导和题解的电子书。这本书主要针对操作系统这个重要的计算机课程内容进行了详细的解释和讲解,对读者学习操作系统具有很大的帮助。 这本电子书的特点是结合了学习指导和题解,旨在帮助读者更好地理解和掌握操作系统的知识。书中通过讲解操作系统的基本概念、原理和技术,引导读者深入理解操作系统的工作原理和实现方法。同时,书中还提供了一些习题和实验,帮助读者巩固所学的知识,提升操作系统的实践能力。 这本电子书的内容丰富全面,涵盖了操作系统的各个方面。包括进程管理、内存管理、文件系统、输入输出管理等内容。每个章节都有详细的解释和示例,配有相关的习题和实验,可以帮助读者更好地理解和运用所学的知识。 对于计算机专业的学生和从事计算机相关工作的技术人员来说,这本电子书是一本很好的学习资料。通过学习这本书,读者可以全面了解和掌握操作系统的知识,提高自己的技能水平。同时,这本电子书还适合作为操作系统相关课程的参考教材,帮助教师更好地教授操作系统的知识。 总之,《计算机操作系统(第4版)》学习指导与题解 含实验.pdf 是一本内容丰富、有助于学习操作系统的电子书,对于学习操作系统或从事计算机相关工作的人士来说都是一本很有价值的学习资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值