https://ac.nowcoder.com/acm/contest/1099#question
emmm...10月8日...昨晚失眠....今天写写水题解。。。好垃圾啊。。。
关于这个题那个点分治明天一定学....
A-全1子矩阵 签到题 给一个n*m的矩阵 一开始全是0 之后把一个矩阵的元素全部设为1 给一个矩阵 判断是不是这样产生的矩阵
思路:输入的时候扫一遍 确定最小的x y(该点并非为1)同时确定最大的x y 之后根据之间的差计算之间1的数量 是否和样例给的1数量相等 但是不知道为什么根据这4个值扫一遍就WA....但是算数量就可以
#include<algorithm> #include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<ctime> #include<map> #include<stack> #include<queue> #include<set> #include<cstring> #include <unordered_set> #include <bitset> #include<unordered_map> using namespace std; const int maxn = 1e6 + 5; char arr[15][15]; int main() { ios::sync_with_stdio(0); int n, m; int sx, sy, ex, ey; int cnt; while (cin >> n >> m) { sx = 100; sy = 100; ex = 0; ey = 0; cnt = 0; for (int i = 0; i < n; i++) {//遍输入遍扫 for (int j = 0; j < m; j++) { cin >> arr[i][j]; if (arr[i][j] == '1') { cnt++; sx = min(sx, i); sy = min(sy, j); ex = max(i, ex); ey = max(j, ey); } } } if (cnt != (ex - sx + 1) * (ey - sy + 1)) cout << "No\n";//互相比较数量看看是否相等 else cout << "Yes\n"; } return 0; }
B-组合数
思路:这个题 前面那部分就是组合数的公式 就是C(n,k) 先优化一个k 保证k是小的那一部分 然后化简为上k项下k项的一个式子 就是高中最常用的那个 然后算 中间就不会炸数 这里我重新敲一遍队长和他们队的代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; const int N = 1e3 + 5; const int INF = 0x3f3f3f3f; ll c[N][N]; void judge(int n, int &k) { if(k > n / 2) k = n - k; } int main() { int n, k; while(~scanf("%d%d", &n, &k)) { judge(n, k); bool ok = false; long double now = 1; for(int i = 1; i <= k; i++) { now *= n - i + 1; now /= k - i + 1; if(now > 1e18) { printf("%0.f\n", 1e18); ok = true; break; } } if(!ok) { printf("%0.Lf\n", now); } } }
E- Numbers
给定0-99个数字 给定一个字符串 每个数字用一次
有多少种组合方式
思路:DFS 具体看代码
#include<algorithm> #include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<ctime> #include<map> #include<stack> #include<queue> #include<set> #include<cstring> #include <unordered_set> #include <bitset> #include<unordered_map> using namespace std; const int maxn = 1e6 + 5; string s; int result = 0; bool vis[100]; void dfs(int i) {//i 代表位数 if (i == s.size()) {//如果正好等于s的长度 result++; } else { int a = s[i] - '0';//这一位当前数字 if (!vis[a]) {//没用过 vis[a] = 1;//用一下 dfs(i + 1);//继续D下一位 vis[a] = 0;//还原 } if (a != 0 && i + 2 <= s.size()) {//这一位不等于0 并且 连续两位没有超过s的最长长度 int b = a * 10 + s[i + 1] - '0';//选定两位 if (!vis[b]) {//同理 vis[b] = 1; dfs(i + 2); vis[b] = 0; } } } } int main() { while (cin >> s) { result = 0; memset(vis, 0, sizeof(vis)); dfs(0);//从0填充开始DFS printf("%d\n", result); } return 0; }
F-4 Buttons
题意 一开始在0,0 之后可以向上下左右四个方向走
最多走abcd 步数 可以走0步 问能到达的所有格子的总数 分四个象限计算 为当前方向全走加上之间所有的点 具体见代码
#include<algorithm> #include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<ctime> #include<map> #include<stack> #include<queue> #include<set> #include<cstring> #include <unordered_set> #include <bitset> #include<unordered_map> using namespace std; const int maxn = 1e6 + 5; const int MOD = 1e9 + 7; typedef long long ll; int n, a[4]; int solve(int n, int a[4]) { int result = 0; for (int i = 0; i < 4; i++) { int x = a[i]; int y = a[(i + 1) % 4]; result += (n * (n - 1LL) / 2 % MOD * x % MOD * y + 1LL*n * x) % MOD; if (result >= MOD) { result -= MOD; } } return result+1; } int main() { while (cin >> n) { for (int i = 0; i < 4; i++) cin >> a[i]; printf("%d\n", solve(n, a)); } return 0; }
J-点分治 明天看看
Comments | NOTHING