本人算法菜鸡,对于CCFCSP认证的345题完全没有信心,今天做这几题,只关注了题目最前面,最简单的测试数据,三个题目骗到65分
防疫大数据(Acwing 4701),20分
只要关注第0天的风险地点和输入的通信信息,其余天份的完全不看
第7天开始就肯定不会有任何风险地点了
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
const int N = 1010;
struct Data
{
int d; //日期
int u; //用户
int r; //地点
bool operator<(const Data& A) {
return u < A.u;
}
} datas[N];
set<int> risk;
set<int> user;
int n;
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n;
int dnum;
for (int i = 0; i < n; i++ ) {
int ri, mi; cin >> ri >> mi;
if (i >= 1) continue;
for (int j = 0; j < ri; j++ ) {
int cd; cin >> cd;
risk.insert(cd); //以及当日收到的风险地区的列表
}
dnum = mi;
for (int k = 0; k < mi; k++ ) {
int d, u, r; cin >> d >> u >> r;
datas[k] = {d, u, r};
if (d == 0 and risk.count(r)) {
user.insert(u);
}
}
}
//所有的风险区都是0-6天
for (int i = 0; i < n; i++ ) {
cout << i << " ";
if (i <= 6) {
for (auto p: user) cout << p << " ";
}
cout << endl;
}
return 0;
}
吉祥物投票(Acwing 4702), 20分
直接把所有人的投票开一个1e5长的数组暴力计算
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
int vote[N];
int ticket[2010];
int n, m, q;
void op1(int l, int r, int x)
{
for (int i = l; i <= r; i++ ) {
int pre = vote[i];
vote[i] = x;
if (pre) { //仅前面是有投票对象,才要减去原来的
ticket[pre]--;
}
}
ticket[x] += r - l + 1; //统计票数
}
void op2(int x, int w)
{
for (int i = 1; i <= n; i++ ) {
if (vote[i] == x) {
vote[i] = w;
ticket[x]-- ;
if (w)
ticket[w]++ ;
}
}
}
void op3(int x, int y)
{
for (int i = 1; i <= n; i++ ) {
if (vote[i] == x) vote[i] = y;
else if (vote[i] == y) vote[i] = x;
}
swap(ticket[x], ticket[y]);
}
int op4(int w)
{
if (w) return ticket[w];
else return count(vote, vote + n, 0);
}
int op5()
{
int max_ticket = 0;
int ticket_res = 0;
for (int i = m; i >= 1; i-- ) {
if (ticket[i] and max_ticket <= ticket[i]) {
max_ticket = ticket[i];
ticket_res = i;
}
}
return ticket_res;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> m >> q;
while (q-- ) {
int cmd; cin >> cmd;
if (cmd == 1) {
int l, r, x; cin >> l >> r >> x;
op1(l, r, x);
}
else if (cmd == 2) {
int x, w; cin >> x >> w;
op2(x, w);
}
else if (cmd == 3) {
int x, y; cin >> x >> y;
op3(x, y);
}
else if (cmd == 4) {
int w; cin >> w;
cout << op4(w) << endl;
}
else {
cout << op5() << endl;
}
}
return 0;
}
高维亚空间超频物质变压缩技术(Acwing 4703),25分
n是18,2进制枚举所有方案,判断是否合法,对于合法的划分方案,计算成本统计最小值
#include <iostream>
#include <numeric>
#include <math.h>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5 + 10;
int v[N], s[N];
int n, L;
vector<vector<int>> div_res(int state)
{
state <<= 1;
vector<vector<int>> res;
vector<int> cur;
for (int pos = n; pos >= 1; pos-- ) {
int c = state & 1;
if (c) {
res.push_back(cur);
cur.clear();
}
cur.push_back(pos);
state >>= 1;
}
if (cur.size()) {
res.push_back(cur);
}
reverse(res.begin(), res.end());
return res;
}
bool is_valid(vector<vector<int>> &div)
{
vector<int> all_mx;
for (int i = 0; i < div.size(); i++ ) {
int mx = s[div[i][0]]; //注意是编号最大的对应神秘质量,不是其中最大的神秘质量
all_mx.push_back(mx);
}
for (int i = 0; i < all_mx.size() - 1; i++ ) {
for (int j = i + 1; j < all_mx.size(); j++ ) {
if (all_mx[i] >= all_mx[j]) return false;
}
}
return true;
}
int cal_score(vector<vector<int>>& div)
{
int sum = 0;
for (vector<int> cur: div) {
int csum = 0;
for (int i = 0; i < cur.size(); i++ ) {
csum += v[cur[i]];
}
sum += (csum - L) * (csum - L);
}
return sum;
}
void print_vector(vector<vector<int>> test);
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> L;
int min_score = 0x3f3f3f3f;
for (int i = 1; i <= n; i++ ) cin >> v[i];
for (int i = 1; i <= n; i++ ) cin >> s[i];
for (int state = 0; state < (1 << (n - 1)); state++ ) {
vector<vector<int>> div = div_res(state);
if (is_valid(div)) {
// print_vector(div);
// cout << endl;
int score = cal_score(div);
min_score = min(min_score, score);
}
}
cout << min_score << endl;
return 0;
}
void print_vector(vector<vector<int>> test)
{
for (int i = 0; i < test.size(); i++ ) {
for (int j = 0; j < test[i].size(); j++ ) {
cout << test[i][j] << ' ';
}
cout << endl;
}
}
有时候想骗4,5题的分都骗不了
真实