https://codeforces.com/contest/1176
https://codeforces.com/contest/1176/standings
A: Divide it!
题意:每个数可以n/2, 2n/3, 3n/5,求变为1的最小次数,不行的话输出-1
贪心
题意:一个数组,可以选泽把两个数求和后合并为一个数,求最多的能被3整数的数的个数
贪心:
mod 3 == 0不处理, 取min(mod3==1, mod3==2),再把剩下的 mod3==1的三个合为一个, mod3==2的三个合为一个
C:Lose it!
实际上就是求原数组可以分为多少个长度为6的数组 [4,8,15,16,23,42]
怎么说呢。。看代码吧
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define reps(i, a, b) for(int i = (a); i < (b); i++)
#define pb push_back
#define ps push
#define mp make_pair
#define CLR(x,t) memset(x,t,sizeof x)
#define LEN(X) strlen(X)
#define F first
#define S second
#define Debug(x) cout<<#x<<"="<<x<<endl;
const double euler_r = 0.57721566490153286060651209;
const double pi = 3.141592653589793238462643383279;
const double E = 2.7182818284590452353602874713526;
const int inf = ~0U >> 1;
const int MOD = int (1e9) + 7;
const double EPS = 1e-6;
typedef long long LL;
int n, x;
int cnt[10];
int cal (int x) {
if (x == 4) return 1;
if (x == 8) return 2;
if (x == 15) return 3;
if (x == 16) return 4;
if (x == 23) return 5;
if (x == 42) return 6;
}
int main() {
cin >> n;
cnt[0] = 10000000;
rep (i, 1, n) {
cin >> x;
x = cal (x);
if (cnt[x - 1] > 0) {
cnt[x - 1]--;
cnt[x]++;
}
}
cout << n - 6 * cnt[6] << endl;
}
题意:有两个数组A和B,初始B=A,遍历A数组,如果A[i]是素数,就把第A[i]个素数加到B数组,否则就把A[i]的最大约数(不是自己)加到B数组.
题目给了B数组,求满足条件的A数组
贪心:
预处理出素数,和素数的位置
倒序枚举每个数,如果是素数,这个素数认为是被A[i]是素数的情况导出来的,否则认为这个数是A数组的数,那么它可以导出一个约数。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define reps(i, a, b) for(int i = (a); i < (b); i++)
#define pb push_back
#define ps push
#define mp make_pair
#define CLR(x,t) memset(x,t,sizeof x)
#define LEN(X) strlen(X)
#define F first
#define S second
#define Debug(x) cout<<#x<<"="<<x<<endl;
const double euler_r = 0.57721566490153286060651209;
const double pi = 3.141592653589793238462643383279;
const double E = 2.7182818284590452353602874713526;
const int inf = ~0U >> 1;
const int MOD = int (1e9) + 7;
const double EPS = 1e-6;
typedef long long LL;
const int maxn = 3000000;
int n;
int a[maxn];
int id[maxn];
bool used[maxn];
//max divisor
int fi (int x) {
for (int i = 2; i * i <= x; i++) if (x % i == 0) return x / i;
}
int main() {
ios::sync_with_stdio (false);
cin.tie (0);
vector<int> p;
vector<int> res;
for (int i = 2; i < maxn; i++) {
if (used[i]) continue;
p.push_back (i);
id[i] = p.size();
for (int j = i + i; j < maxn; j += i) {
used[j] = true;
}
}
cin >> n;
n <<= 1;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
a[x]++;
}
for (int i = maxn - 1; i >= 2; i--) {
while (a[i]) {
if (!used[i]) {
//i is prime
res.push_back (id[i]);
a[id[i]]--;
} else {
res.push_back (i);
a[fi (i)]--;
}
a[i]--;
}
}
for (int x : res) {
cout << x << " ";
}
cout << endl;
return 0;
}
一个无相连通图,求选择一个顶点集( 个数<= n/2),使得剩下的每个顶点都和所选的顶点集有边相连.
黑白染色,选个数<=n/2的那个集合
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define reps(i, a, b) for(int i = (a); i < (b); i++)
#define pb push_back
#define ps push
#define mp make_pair
#define CLR(x,t) memset(x,t,sizeof x)
#define LEN(X) strlen(X)
#define F first
#define S second
#define Debug(x) cout<<#x<<"="<<x<<endl;
const double euler_r = 0.57721566490153286060651209;
const double pi = 3.141592653589793238462643383279;
const double E = 2.7182818284590452353602874713526;
const int inf = ~0U >> 1;
const int MOD = int (1e9) + 7;
const double EPS = 1e-6;
typedef long long LL;
const int maxn = 200020;
int n, m;
int a[maxn];
vector<int> v[maxn];
//black-white ranse
void dfs (int x, int c) {
if (a[x] > 0) {
return ;
}
a[x] = c;
for (int y : v[x]) {
dfs (y, 3 - c);
}
}
void solve() {
cin >> n >> m;
rep (i, 1, n) v[i].clear(), a[i] = 0;
rep (i, 1, m) {
int x, y;
cin >> x >> y;
v[x].push_back (y);
v[y].push_back (x);
}
dfs (1, 1);
vector<int> A, B;
rep (i, 1, n) {
if (a[i] == 1) A.push_back (i);
else B.push_back (i);
}
if (B.size() < A.size()) A = B;
cout << A.size() << endl;
for (int x : A) {
cout << x << " ";
}
cout << endl;
}
int main() {
int T;
cin >> T;
while (T--) {
solve();
}
}
打boss,一共有n轮,每轮你有一些卡片,每个卡牌有两个属性cost、damage.每一轮你可以选择一些卡片,他们c的和不能超过3,会造成d的伤害(选的卡牌的d的和).每第10张卡片会造成双倍伤害,求最大值.
可以看下样例给的解释,非常清楚。
做法:应该是dp,但是我不会。。。