2017年浙江工业大学大学生程序设计迎新赛热身赛

吐槽一下,这套题作为迎新热身好像有点难阿


A

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e6 + 10;
const int INF = 1e9 + 10;
char ans[45];
 
int main(){
    int t;  scanf("%d", &t) ;
    while (t--) {
        int n;  scanf("%d", &n) ;
        double maxn = 0, x, y ;
        char tmp[45];
        for (int i = 1; i <= n; ++i) {
            scanf("%s%lf%lf", tmp, &x, &y) ;
            if (i == 1) {
                strcpy(ans, tmp);
                maxn = x / y;
            } else {
                if(maxn < x * 1.0 / y) {
                    maxn = x / y;
                    strcpy(ans, tmp);
                }
            }
        }
        printf("%s\n", ans);
    }
    return 0;
}


C

首先判断三点是否贡献,然后根据叉积判断原点是否在三角形内部

判断点是否在三角形内可以参考:小宫呀

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
int x[3], y[3];
int f[3];
bool isConLine() {
    if (x[1] - x[0] == 0 || x[2] - x[0] == 0) {
        if (x[1] - x[0] == 0 && x[2] - x[0] == 0) {
            return true;
        } else {
            return false;
        }
    }
    if((y[1] - y[0]) * (x[2] - x[0]) == (x[1] - x[0]) * (y[2] - y[0]))
        return true;
    return false;
}
void getDir(int l, int r) {
    int flag = (x[r] - x[l]) * (0 - y[l]) - (y[r] - y[l]) * (0 - x[l]);
    if (flag < 0)    f[l] = -1;
    else if(flag > 0)    f[l] = 1;
    else    f[l] = 0;
}
 
int main(){
    int t;  scanf("%d", &t);
    while (t--) {
        for (int i = 0; i < 3; ++i) {
            scanf("%d%d", x + i, y + i);
        }
        if (isConLine()) {
            puts("NO");
            continue;
        }
//      puts("QQQ");
        bool flag = false;
        int cnt = 0;
        for (int i = 0; i < 3; ++i) {
            getDir(i, (i + 1) % 3);
            if (f[i] == 0)  flag = true;
            if (f[i] > 0)    cnt++;
        }
//      printf("%d\n", cnt);
        if (flag) {
            puts("NO");
            continue;
        }
        if (cnt == 3 || cnt == 0) {
            puts("YES");
        } else {
            puts("NO");
        }
    }
    return 0;
}


E

这题是一个裸的矩阵快速幂,构造出矩阵即可

可以参考16年沈阳区域赛的C题 好像是C

- - 这题居然不是MOD 1e9 + 7,真是丧心病狂阿,还自己写了个对拍 (装傻)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1000000009;
const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
//LL n;
struct Mar {
    LL mar[4][4] ;
    Mar () {
        mst(mar, 0);
    }
    Mar operator * (const Mar &a) const {
        Mar tmp;
        mst(tmp.mar, 0);
        for(int i = 0; i < 4; ++i) {
            for(int j = 0; j < 4; ++j) {
                for(int k = 0; k < 4; ++k) {
                    tmp.mar[i][j] += (mar[i][k] * a.mar[k][j] % MOD);
                    tmp.mar[i][j] %= MOD;
                }
            }
        }
        return tmp;
    }
}ans, unit;
LL Solve (LL n) {
    n -= 1;
    mst(unit.mar, 0);
    for(int i = 0; i < 4; ++i) {
        unit.mar[i][i] = 1;
    }
    mst(ans.mar, 0);
    ans.mar[0][0] = 2, ans.mar[0][1] = 1, ans.mar[0][2] = 2, ans.mar[0][3] = 1;
    ans.mar[1][1] = 1, ans.mar[1][2] = 2, ans.mar[1][3] = 1;
    ans.mar[2][2] = 1, ans.mar[2][3] = 1;
    ans.mar[3][3] = 1;
    while(n > 0) {
        if(n & 1)   unit = unit * ans;
        ans = ans * ans;
        n >>= 1;
    }
    LL sum = 0;
    for(int i = 0; i < 4; ++i) {
        sum = (sum + unit.mar[0][i]) % MOD;
    }
    return sum;
}
LL dp[100005] ;
void Init () {
    for(int i = 2; i <= 46500; ++i) {
        if(dp[i] != Solve(i))   printf("%d\n", i);
    }
}
 
int main () {
    LL n;
    while (scanf("%lld", &n) != EOF) {
        if(n == 0) {
            printf("0\n");
        } else if (n == 1) {
            printf("1\n");
        } else {
            printf("%lld\n", Solve(n)) ;
        }
    }
//  Init();
    return 0;
}


G

这题思想基本就是对每一种颜色进行尺取,我这里离散化了一下

也有类似的题,可以参考2017年百度之心初赛的这道题:小宫呀

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
int c[qq], tmp[qq];
int n, k;
vector<int> vt[qq];
void solve() {
    int maxn = 1;
    for (int i = 0; i < qq; ++i) {
        if(vt[i].size() == 0)   continue;
        int t = k, l = 0, cnt = 1;
        for (int j = 1; j < vt[i].size(); ++j) {
            int gap = vt[i][j] - vt[i][j - 1] - 1;
            cnt++;
            t -= gap;
            while (t < 0 && l < j) {
                l++;
                t += (vt[i][l] - vt[i][l - 1] - 1);
                cnt--;
            }
            maxn = max(maxn, cnt);
        }
    }
    printf("%d\n", maxn);
    for (int i = 0; i < qq; ++i) {
        vt[i].clear();
    }
}
 
int main(){
    while (scanf("%d%d", &n, &k) != EOF) {
        for (int i = 0; i < n; ++i) {
            scanf("%d", c + i);
            tmp[i] = c[i];
        }
        sort(tmp, tmp + n);
        int h = unique(tmp, tmp + n) - tmp;
        for (int i = 0; i < n; ++i) {
            c[i] = (lower_bound(tmp, tmp + h, c[i]) - tmp);
            vt[c[i]].pb(i);
//          printf("%d ", c[i]);
        }
//      puts("");
        solve();
    }
    return 0;
}


H

仔细分析一下发现其实是一个线段树的区间加减维护单点最值的问题

我们考虑每一个数对当前遍历到的所有数的贡献

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
int a[qq], b[qq], n, m;
LL sum[4 * qq], lazy[4 * qq];
vector<int> G[qq];
void pushUp(int rt) {
	sum[rt] = max(sum[lson], sum[rson]);
}
void pushDwon(int rt) {
	if (lazy[rt]) {
		sum[lson] += lazy[rt];
		sum[rson] += lazy[rt];
		lazy[lson] += lazy[rt];
		lazy[rson] += lazy[rt];
		lazy[rt] = 0;
	}
}
void build(int l, int r, int rt) {
	lazy[rt] = sum[rt] = 0;
	if (l == r) {
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, lson);
	build(mid + 1, r, rson);
}
void upDate(int l, int r, int rt, int x, int y, int val) {
	if (x <= l && r <= y) {
		sum[rt] += val;
		lazy[rt] += val;
		return;
	}
	pushDwon(rt);
	int mid = (l + r) >> 1;
	if(x <= mid)	upDate(l, mid, lson, x, y, val);
	if(mid < y)		upDate(mid + 1, r, rson, x, y, val);
	pushUp(rt);
}


int main(){
	while (scanf("%d%d", &n, &m) != EOF) {
		for (int i = 1; i <= n; ++i) {
			scanf("%d", a + i);
		}
		for (int i = 1; i <= m; ++i) {
			scanf("%d", b + i);
		}
		build(1, n, 1);
		LL maxn = 0;
		for (int i = 1; i <= n; ++i) {
			if (G[a[i]].size() == 0) {
				upDate(1, n, 1, 1, i, b[a[i]]);
			} else if(G[a[i]].size() == 1) {
				upDate(1, n, 1, 1, G[a[i]][0], -b[a[i]]);
				upDate(1, n, 1, G[a[i]][0] + 1, i, b[a[i]]);
			} else {
				upDate(1, n, 1, G[a[i]][G[a[i]].size() - 2] + 1, G[a[i]][G[a[i]].size() - 1], -b[a[i]]);
				upDate(1, n, 1, G[a[i]][G[a[i]].size() - 1] + 1, i, b[a[i]]);
			}
			G[a[i]].pb(i);
			maxn = max(maxn, sum[1]);
		}
		printf("%lld\n", maxn);
		for (int i = 1; i <= m; ++i) {
			G[i].clear();
		}
	}
	return 0;
}



I

是个简单的bfs,关键是考虑你在走到魔法书的位置时不能同时经过M和F,那么我们可以这么考虑,一条合法的路径

1.不经过任何M和F

2.只经过M

3.只经过F

2,3这两种情况无非就是把对应的M或者F变成可以行走的点‘.’

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e3 + 10;
const int INF = 1e9 + 10;
char st[qq][qq];
bool vis[qq][qq];
int n, m, r, c;
struct Node {
    int x, y;
    int Time;
}now, tmp;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
bool check(int x, int y, char flag) {
    if(x < 1 || y < 1 || x > n || y > m)    return false;
    if(vis[x][y] || st[x][y] == '*')    return false;
    if(st[x][y] != flag && st[x][y] != '.') return false;
    return true;
}
int bfs(char flag) {
    queue<Node> Q;
    mst(vis, false);
    now.x = 1, now.y = 1, now.Time = 0;
    Q.push(now);
    vis[1][1] = true;
    while (!Q.empty()) {
        now = Q.front();
        Q.pop();
        if (now.x == r && now.y == c) {
            return now.Time;
        }
        tmp.Time = now.Time + 1;
        for(int i = 0; i < 4; ++i) {
            tmp.x = now.x + dx[i];
            tmp.y = now.y + dy[i];
            if(!check(tmp.x, tmp.y, flag))  continue;
            Q.push(tmp);
            vis[tmp.x][tmp.y] = true;
        }
    }
    while (!Q.empty()) Q.pop();
    return INF;
}
 
int main(){
    int t;  scanf("%d", &t);
    while (t--) {
        scanf("%d%d%d%d", &n, &m, &r, &c);
        for (int i = 1; i <= n; ++i) {
            scanf("%s", st[i] + 1);
        }
        int minx = min(bfs('M'), bfs('F'));
        if(minx == INF) puts("IMPOSSIBLE");
        else    printf("%d\n", minx * 2);
    }
    return 0;
}


J

这题是以前一场cf div2的C题,具体证明可以参考哥德巴赫猜想

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e6 + 10;
const int INF = 1e9 + 10;
bool isPrime(int x) {
    for(int i = 2; i * i <= x; ++i) {
        if(x % i == 0)  return false ;
    }
    return true ;
}
 
int main(){
    int t;  scanf("%d", &t) ;
    while (t--) {
        int n;  scanf("%d", &n) ;
        bool f = isPrime(n) ;
        if(f) {
            puts("1") ;
        } else if(n % 2 == 0) {
            puts("2") ;
        } else {
            if(isPrime(n - 2)) {
                puts("2");
            } else {
                puts("3");
            }
        }
    }
    return 0;
}


并且这个猜想可以认为在 long long可以表示的数的范围内是正确的




K

很裸的一个分组背包

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e3 + 10;
const int INF = 1e9 + 10;
int dp[qq], n, m;
vector<int> a[qq], b[qq];
 
int main(){
    int t;  scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; ++i) {
            int k;  scanf("%d", &k);
            for(int x, j = 0; j < k; ++j) {
                scanf("%d", &x);
                b[i].pb(x);
            }
            for(int x, j = 0; j < k; ++j) {
                scanf("%d", &x);
                a[i].pb(x);
            }
        }
        mst(dp, 0);
        for(int i = 0; i < n; ++i) {
            for(int j = m; j >= 0; --j) {
                for(int k = 0; k < a[i].size(); ++k) {
                    if(j - a[i][k] < 0)  continue;
                    dp[j] = max(dp[j], dp[j - a[i][k]] + b[i][k]);
                }
            }
        }
        printf("%d\n", dp[m]);
        for(int i = 0; i < n; ++i) {
            a[i].clear();
            b[i].clear();
        }
    }
    return 0;
}


L

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
 
int main(){
    int t;  scanf("%d", &t);
    while (t--) {
        int a, b;   scanf("%d%d", &a, &b);
        int tm = b - a;
        if (a == 1 && b == 0) {
            printf("1\n");
        } else if (b == 15) {
            printf("14\n") ;
        } else {
            printf("%d\n", b + tm);
        }
    }
    return 0;
}


M

(a + b) % c = 0  等价于 ( (a % c) + (b % c) ) % c = 0

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b)   memset(a, b, sizeof a)
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e6 + 10;
const int INF = 1e9 + 10;
int n, m;
int a[qq], b[qq];
LL num1[33], num2[33];
LL Solve(int x) {
    mst(num1, 0), mst(num2, 0);
    for(int i = 1; i <= n; ++i) {
        num1[a[i] % x]++ ;
    }
    for(int i = 1; i <= m; ++i) {
        num2[b[i] % x]++ ;
    }
    LL ans = 0;
    for(int i = 0; i < x; ++i) {
        ans += num1[i] * num2[x - i];
    }
    ans += num1[0] * num2[0];
    return ans;
}
 
int main(){
    int t;  scanf("%d", &t) ;
    while(t--) {
        scanf("%d%d", &n, &m) ;
        for(int i = 1; i <= n; ++i) {
            scanf("%d", a + i) ;
        }
        for(int i = 1; i <= m; ++i) {
            scanf("%d", b + i) ;
        }
        LL ans = 0;
        ans += Solve(3) + Solve(7) - Solve(21);
        printf("%lld\n", ans);
    }
    return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值