1005
直接dp即可
#include <bits/stdc++.h> using namespace std; int dp[5005][5005]; int N; int a[5005]; const int MOD = 1e9+7; int main(){ int T; cin >> T; while (T--){ int N; memset(dp,0,sizeof(dp)); dp[1][1] = 1; scanf("%d",&N); for (int i = 1 ; i <= N ; i ++){ scanf("%d",&a[i]); } sort(a+1,a+N+1); for (int i = 2 ; i <= N ; i ++) if (a[i] == a[i-1]) dp[i][1] = dp[i-1][1]; else dp[i][1] = dp[i-1][1]+1; for (int i = 2 ; i <= N ; i++) for (int j = 2 ; j <= i ; j ++){ if (i == j) dp[i][j] = dp[i][j-1]; else if (a[i] == a[i-1]) dp[i][j] = dp[i-1][j]; else dp[i][j] = (dp[i][j-1]+dp[i-1][j])%MOD; } for (int i = 1 ; i <= N ; i ++) printf("%d\n",dp[N][i]); } return 0; }
1011
队友写的,似乎是个大模拟?
#include <bits/stdc++.h> #define x first #define y second using namespace std; typedef long long LL; typedef pair< int, int > PII; const int N = 55; int n, z; char s[N][N]; int read() { int res = 0, w = 1; char ch = getchar(); while (ch != '-' && !isdigit(ch)) ch = getchar(); if (ch == '-') w = -1, ch = getchar(); while (isdigit(ch)) res = res * 10 + ch - '0', ch = getchar(); return res * w; } void solve() { scanf("%d%d", &n, &z); memset(s, 0, sizeof 0); for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1); // cout << "---" << endl; // for (int i = 1; i <= n; i++) // { // for (int j = 1; j <= n; j++) // cout << s[i][j]; // cout << endl; // } if ((n * z) % 100) { cout << "error" << endl; return; } if (z == 100) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cout << s[i][j]; cout << endl; } return; } if (z == 125) { for (int i = 1; i <= n; i += 4) for (int j = 1; j <= n; j += 4) { char ch = s[i][j]; for (int u = i; u < i + 4; u++) for (int v = j; v < j + 4; v++) if (s[u][v] != ch) { cout << "error" << endl; return; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j += 4) { for (int k = 1; k <= 5; k++) cout << s[i][j]; } cout << endl; if (i % 4 == 1) { for (int j = 1; j <= n; j += 4) { for (int k = 1; k <= 5; k++) cout << s[i][j]; } cout << endl; } } } if (z == 150) { for (int i = 1; i <= n; i += 2) for (int j = 1; j <= n; j += 2) { char ch = s[i][j]; for (int u = i; u < i + 2; u++) for (int v = j; v < j + 2; v++) if (s[u][v] != ch) { cout << "error" << endl; return; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j += 2) { for (int k = 1; k <= 3; k++) cout << s[i][j]; } cout << endl; if (i % 2 == 1) { for (int j = 1; j <= n; j += 2) { for (int k = 1; k <= 3; k++) cout << s[i][j]; } cout << endl; } } return; } if (z == 175) { for (int i = 1; i <= n; i += 4) for (int j = 1; j <= n; j += 4) { char ch = s[i][j]; for (int u = i; u < i + 4; u++) for (int v = j; v < j + 4; v++) if (s[u][v] != ch) { cout << "error" << endl; return; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j += 4) { for (int k = 1; k <= 7; k++) cout << s[i][j]; } cout << endl; if (i % 4 == 1) { for (int j = 1; j <= n; j += 4) { for (int k = 1; k <= 7; k++) cout << s[i][j]; } cout << endl; for (int j = 1; j <= n; j += 4) { for (int k = 1; k <= 7; k++) cout << s[i][j]; } cout << endl; for (int j = 1; j <= n; j += 4) { for (int k = 1; k <= 7; k++) cout << s[i][j]; } cout << endl; } } return; } if (z == 200) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { for (int k = 1; k <= 2; k++) cout << s[i][j]; } cout << endl; for (int j = 1; j <= n; j++) { for (int k = 1; k <= 2; k++) cout << s[i][j]; } cout << endl; } } } int main() { int T = 1; scanf("%d", &T); while (T--) { solve(); } return 0; }
1012
首先,可以把加的过程变成减的过程
然后就会发现这东西和gcd的那个更相减损术非常类似
于是就会考虑在辗转相除法的过程中,记录一下每个数对的情况所能达到的情况,并且排个序
每次查询的时候,就二分一下它在路径上的位置,算一个后缀个数即可。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 50010; struct node { ll x, y; bool operator < (const node &g) const { return x == g.x ? y < g.y : x < g.x; } } ; map<ll, int> t; map<node, vector<ll> > pre; int T, n, q; ll a[N], b[N]; void gcd(ll x, ll y) { if (!x || !y) return ; if (x < y) { pre[(node){x, y % x}].push_back(y); gcd(x, y % x); } else { pre[(node){x % y, y}].push_back(x); gcd(x % y, y); } } int main() { scanf("%d", &T); for ( ; T; T--) { scanf("%d%d", &n, &q); t.clear(), pre.clear(); for (int i = 1; i <= n; i++) { scanf("%lld%lld", &a[i], &b[i]); if (a[i] == b[i]) { t[a[i]]++; continue; } gcd(a[i], b[i]); if (a[i] < b[i]) pre[(node){a[i], b[i]}].push_back(a[i]); else pre[(node){a[i], b[i]}].push_back(b[i]); } for (auto &[u,v]:pre){ sort(v.begin(),v.end()); } for (int i = 1; i <= q; i++) { ll c, d; scanf("%lld%lld", &c, &d); int cnt = 0; if (c == d) cnt = t[c]; if (c <= d) { node g = (node){c, d % c}; int siz = pre[g].size(); int l = lower_bound(pre[g].begin(),pre[g].end(),d)-pre[g].begin(); /*while (l < r) { int mid = (l + r) >> 1; if (now[mid] < d) l = mid + 1; else r = mid; }*/ cnt += siz - l; } if (c >= d) { node g = (node){c % d, d}; int siz = pre[g].size(); /*while (l < r) { int mid = (l + r) >> 1; if (now[mid] < c) l = mid + 1; else r = mid; }*/ int l = lower_bound(pre[g].begin(),pre[g].end(),c)-pre[g].begin(); cnt += siz - l; } printf("%d\n", cnt); } } return 0; }
1004
因为是全随机的数据
所以考虑每一个可能的$\delta X$和 $\delta Y$
随机抽取$100$个可能的值,然后考虑它是否合法
不合法就退出
因为数据全随机,所以其实不合法的概率非常高
#include <bits/stdc++.h> #define pii pair<int,int> using namespace std; int T; int N; pii a[200005]; map<pii,int> cnt; int Random(int MOD){ return 1ll*rand() * 1ll*rand()%MOD*1ll*rand()%MOD; } int main(){ srand(time(NULL)); cin >> T; while (T--){ cin >> N; cnt.clear(); for (int i = 1 ; i <= 2 * N ; i ++){ cin >> a[i].first >> a[i].second; cnt[a[i]] ++; } vector<pii> ans; for (int i = 2 ; i <= 2 * N ; i ++){ cnt[a[1]] --; cnt[a[i]] --; int deltaX = a[i].first - a[1].first,deltaY = a[i].second - a[1].second; int TT = 1000; bool flag = false; while (TT --){ int x = Random(2*N); x++; if ( x ==1 || x == i) continue; //cout << x << endl; pii New = {a[x].first + deltaX,a[x].second + deltaY}; pii New1 ={a[x].first - deltaX,a[x].second - deltaY}; if (cnt[New] + cnt[New1] < cnt[a[x]]){ flag = true; break; } } if (!flag) { ans.push_back({deltaX,deltaY}); ans.push_back({-deltaX,-deltaY}); } cnt[a[1]] ++; cnt[a[i]] ++; } bool flag = false; for (int i = 1 ; i <= 2 * N ; i ++) if (cnt[a[i]] %2 != 0){ flag = true; break; } if (flag == false) ans.push_back({0,0}); sort(ans.begin(),ans.end()); ans.erase(unique(ans.begin(),ans.end()),ans.end()); int cntt = 0; for (auto v : ans){ if (flag == true && v.first == 0 && v.second == 0) continue; cntt ++; } cout << cntt << '\n'; for (auto v : ans){ if (flag == true && v.first == 0 && v.second == 0) continue; cout << v.first << " " << v.second << '\n'; } } return 0; }
标签:pre,杭电多校,cnt,ch,node,int,mid,2023,第三场 From: https://www.cnblogs.com/si--nian/p/17583492.html