南昌大学航天杯第二届程序设计竞赛校赛网络同步赛 部分题解

A-ID and password
签到题。

#include 
#include 
#include 
#include 
const int N = 5e4;

using namespace std;
char s[N];

int main() {
    while(~scanf("%s",s))
    {
        for(int i = 0; s[i]; ++i){
            if(s[i]>='a'&&s[i]<='z'){
                putchar(toupper(s[i]));
            }else{
                putchar(tolower(s[i]));
            }
        }
        puts("");
    }
    return 0;
}

B-取石子
尼姆博弈。
正确做法是每堆每次可以取1,3,9个石子,通过递推和循环得到每个数量的sg值,最后异或一下就是答案。但是吧。。。蒻当时就是蒙的。。。当两堆石子总数为偶数时先手必输,奇数必赢。为什么呢?你想啊,如果石子总数为偶数,先手拿肯定会将石子数变为奇数,后手总是可以再次将石子数变为偶数,最后一次先手拿后,后手就可以拿完了。(比如剩下5个,后手就可以拿一个或者三个,然后剩下4个或者2个,所以这样推下去肯定先手必败)
先上一下标程吧…

#include 

using namespace std;
const int MAXN = 125;

int sg[MAXN][MAXN];

int dfs(int x, int y) {

    if(sg[x][y] == 1) {
        return 1;
    }
    if(sg[x][y] == 0) {
        return 0;
    }
    int ok  = 0;
    if(x >= 1) {
        ok |= dfs(x - 1, y);
    }
    if(x >= 3) {
        ok |= dfs(x - 3, y);
    }
    if(x >= 9) {
        ok |= dfs(x - 9, y);
    }
    if(y >= 1) {
        ok |= dfs(x, y - 1);
    }
    if(y >= 3) {
        ok |= dfs(x, y - 3);
    }
    if(y >= 9) {
        ok |= dfs(x, y - 9);
    }
    return sg[x][y] = !ok;
}

inline void init() {
    memset(sg, -1, sizeof(sg));
    sg[0][0] = 1;
    for(int i = 0; i <= 100; i++ ) {
        for(int j = 0; j <= 100; j++ ) {
            if(sg[i][j] == -1) {
                dfs(i, j);
            }
        }
    }
}

int main()
{
    int x, y;
    init();
    while(~scanf("%d %d", &x, &y)) {
        if(sg[x][y] == 1) {
            puts("lose");
        } else {
            puts("win");
        }
    }

    return 0;
}

其次可以取巧…

#include 
using namespace std;
int main()
{
    int n1,n2;
    while (~scanf("%d%d",&n1,&n2)) {
        if((n1+n2)%2==0){
            printf("lose\n");
        }else {
            printf("win\n");
        }
    }
    return 0;
}

C-水题
题意说要满足条件“地图中不能有任意三个城市可以互相直达”,那么我们就可以将城市分为两组,让组内的城市不能随意连接,组间的可以随意连接,这样就满足条件了。这样要求最大道路数,那么就让第一组的城市数量与第二组的城市数量乘积最大就好了啦~

#include 
using namespace std;
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        printf("%d\n",n/2*(n-n/2));
    }
    return 0;
}

D-小C的记事本
按题意模拟即可,用一个栈保存操作1和2的状态,操作4即出栈。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
const int N = 1e6+1;
using namespace std;
int main()
{
//    if(freopen("in.txt","r",stdin)==NULL){
//        printf("no\n");
//    }
    ios::sync_with_stdio(false);

    int n,op,k;
    while(cin>>n)
    {
        string s = "",b;
        stack<string> st;
        while(n--)
        {
            cin>>op;
            if(op==1){
                cin>>b;
                st.push(s);
                s+=b;
            }else if(op==2){
                cin>>k;
                st.push(s);
                s = s.substr(0,s.size()-k);
            }else if(op==3){
                cin>>k;
                cout<1]<else if(op==4){
                s = st.top();
                st.pop();
            }
        }
    }
    return 0;
}

F-阿汤的疑惑
这里蒻用的java,因为读入的数据太大,用c++的话需要字符串存储,然后转换成整型时对m取模。
题意就是先n对m取模,然后分解质因数,蒻的做法是事先打素数表(数组一定要开大点。。蒻wa23次,一直卡在90%,最后发现是数组没开够)java大数读入n再对m取模,然后用事先打好的素数表找质因数就好了。

import java.util.Scanner;
import java.math.*;

public class Main {
    static int N = 10000000,k=0;
    static int prime[] = new int[N];
    static boolean book[] = new boolean[N];

    public static void init(){
        for(int i = 2; i < N; ++i){
            if(book[i]==false){
                prime[k++] = i;
            }
            for(int j = 2; i*j < N; ++j){
                if(book[i*j]==false){
                    book[i*j] = true;
                }
            }
        }
    }

    public static void main(String[]args){
        Scanner in = new Scanner(System.in);
        init();
        int t = in.nextInt();
        for(int j = 0; j < t; ++j){
            BigInteger n = in.nextBigInteger();
            int m = in.nextInt();
            BigInteger mod = n.mod(BigInteger.valueOf(m));
            int n1 = mod.intValue();
            int cnt = 0;
            for(int i= 0; i < k; ++i){
                if(n1%prime[i]==0){
                    cnt++;
                }
            }
            System.out.println(cnt);
        }
        in.close();
    }
}

I-小q的时钟
签到题。对差除以3600得到小时,对差模60得到秒数,再用差减去小时占去的秒数除以60得到分钟。

#include 
using namespace std;

int main() {
    long long n,e;
    while(~scanf("%lld%lld",&n,&e))
    {
        long long ans = e-n;
        int s = ans%60;
        long long h = ans/3600;
        int m = (ans-h*3600-s)/60;
        if(h<100){
            printf("%02lld:",h);
        }else{
            printf("%lld:",h);
        }
        printf("%02d:%02d\n",m,s);
    }
    return 0;
}

你可能感兴趣的:(算法,ACM,牛客,ACM)