直接判断两个数是否互质
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #pragma GCC optimize(2) #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define one first #define two second using namespace std; typedef long long ll; typedef pair<int, int > PII; const int N = 1e6 + 5, mod = 1e9 + 9, INF = 0x3f3f3f3f; int t, a, b; int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); cin.tie(0); cout.tie(0); ios::sync_with_stdio(0); cin >> t; while (t--) { cin >> a >> b; if (gcd(a, b) == 1) puts("Finite"); else puts("Infinite"); } }
贪心
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #pragma GCC optimize(2) #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define one first #define two second using namespace std; typedef long long ll; typedef pair<int, int > PII; const int N = 200, mod = 1e9 + 9, INF = 0x3f3f3f3f; int t, a, b, c, flag, tmp, m, n; char s1[N], s2[N]; int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // cin.tie(0); // cout.tie(0); // ios::sync_with_stdio(0); cin >> t; while (t--) { tmp = 0; mm(s2, 0); cin >> n >> a >> b >> c; scanf("%s", s1); for (int i = 0; i < n; ++i) { if (s1[i] == 'R') { if (b > 0) { tmp++; b--; s2[i] = 'P'; } else { s2[i] = 'X'; } } else if (s1[i] == 'P') { if (c > 0) { c--; tmp++; s2[i] = 'S'; } else { s2[i] = 'X'; } } else if (s1[i] == 'S') { if (a > 0) { tmp++; a--; s2[i] = 'R'; } else { s2[i] = 'X'; } } } if (n & 1) m = n / 2 + 1; else m = n / 2; // cout << tmp << " " << m << endl; if (tmp < m) { puts("NO"); continue; } else { for (int i = 0; i < n; ++i) { if (s2[i] == 'X') { if (a > 0) { s2[i] = 'R'; a--; } else if (b > 0) { s2[i] = 'P'; b--; } else if (c > 0) { c--; s2[i] = 'S'; } } } printf("YES "); printf("%s ", s2); } } } /* 7 2 1 1 0 RR 2 2 0 0 SS 2 2 0 0 RR 3 1 2 0 RRR 3 2 1 0 RRR 1 1 0 0 P 1 1 0 0 S */
如果字符中出现m或w就代表是由好的打印机发过来的,直接输出0。否则就dp推一下状态转移方程,后来发现如果当前字符为n或u并且前一个字符也为n或u就是dp[n] = dp[n - 1] + dp[n - 2],否则dp[n] = dp[n - 1]
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #pragma GCC optimize(2) #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define one first #define two second using namespace std; typedef long long ll; typedef pair<int, int > PII; const int N = 1e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; char s[N]; int dp[N]; int ans, flag; int pow_2(int x) { int ans = 2; for (int i = 1; i <= x; ++i) ans *= 2; return ans; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // cin.tie(0); // cout.tie(0); // ios::sync_with_stdio(0); scanf("%s", s); flag = 0; int len = strlen(s); dp[0] = 1; for (int i = 0; i < len; ++i) { if (s[i] == 'm' || s[i] == 'w') { flag = 1; break; } if (i == 0) continue; if (i == 1) { if (s[i] == s[i - 1]) dp[i] = dp[i - 1] + 1; else dp[i] = dp[i - 1]; continue; } if (s[i] == 'u' && s[i - 1] == 'u') dp[i] = (dp[i - 1] + dp[i - 2]) % mod; else if (s[i] == 'n' && s[i - 1] == 'n') dp[i] = (dp[i - 1] + dp[i - 2]) % mod; else dp[i] = dp[i - 1]; // if (s[i] == 'n') { // if (i == 1) { // if (s[i - 1] == 'n') dp[i] = dp[i - 1] * 2; // else dp[i] = dp[i - 1]; // continue; // } // if (s[i - 1] == 'n' && s[i - 2] == 'n') dp[i] = dp[i - 1] + dp[i - 2]; // else if (s[i - 1] == 'n') dp[i] = (dp[i - 1] + 1) * dp[i - 1]; // else dp[i] = dp[i - 1]; // } else if (s[i] == 'u') { // if (i == 1) { // if (s[i - 1] == 'u') dp[i] = dp[i - 1] + 1; // else dp[i] = dp[i - 1]; // continue; // } // if (s[i - 1] == 'n' && s[i - 2] == 'u') dp[i] = dp[i - 1] + dp[i - 2]; // else if (s[i - 1] == 'u') dp[i] = dp[i - 1] + 1; // else dp[i] = dp[i - 1]; // } else { // dp[i] = dp[i - 1]; // } // // cout << i << " " << dp[i] << endl; } if (flag == 1) { puts("0"); } else { cout << dp[len - 1] << endl; } }
题意:要使每个村庄都通上电,通电的方法是在这个村庄建发电站(花费ci)或者把这个村庄和一个有发电站的村庄连接起来(花费ki + kj的和乘上两个村庄的曼哈顿距离)
这题显然是最小生成树(感觉迪杰斯特拉也行)
解法:首先假设每个点都自建,那么每个点的代价就是自建代价。然后按照代价排序,用代价最小的点去更新后面那些点,如果能更新用电代价,就把那些点连接到当前点。然后进入下一轮循环,排除上一次代价最小的点,把剩下的点再次按照代价排序,然后用这些点中代价最小的去更新其他的,以此类推。
By MengWH, contest: Codeforces Round #597 (Div. 2), problem: (D) Shichikuji and Power Grid, Accepted, # #include<bits/stdc++.h> using namespace std ; int n; struct City { int id; long long x,y; //坐标 long long cc,kk; //自建的花费,连线的花费 bool self;//是否建站 int fa;//连线的站 bool operator < (const City & a)const { return cc<a.cc; } } c[2005]; int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { c[i].id=i;//发电站编号 c[i].self=1; //首先都默认是自建的 scanf("%lld%lld",&c[i].x,&c[i].y); //输入坐标 } for(int i=1; i<=n; i++) scanf("%lld",&c[i].cc); //初始都为自建 for(int i=1; i<=n; i++) scanf("%lld",&c[i].kk);//连线 long long ans=0,selfnum=0; for(int i=1; i<=n; i++) { sort(c+i,c+1+n);//大概就是要随时排序,每次找到最小的,每次排序要排除前一次的,防止多加费用 ans+=c[i].cc; //费用 if(c[i].self) selfnum++; //判断是否自建 for(int j=i+1; j<=n; j++) { long long cost=(c[i].kk+c[j].kk)*(abs(c[i].x-c[j].x)+abs(c[i].y-c[j].y)); if(cost<c[j].cc) { c[j].cc=cost; c[j].self=0;//放弃自建,说要已经和别的站建立了联系 c[j].fa=c[i].id; } } } printf("%lld %lld ",ans,selfnum); for(int i=1; i<=n; i++) if(c[i].self) printf("%d ",c[i].id); printf(" %lld ",n-selfnum); for(int i=1; i<=n; i++) if(!c[i].self) printf("%d %d ",c[i].id,c[i].fa); return 0; }
E、F
......