RC-u4 攻略分队

题意
把 6 支队伍分成两组,把所有的可能方案按照下面的筛选方式找到最佳方案:

思路
比较简洁的一个方法是,将每一条方案中的元素都存储到结构体中,然后在结构体中重载运算符,根据给出的筛选策略将所有方案排序,排过序之后的首条方案便是最佳方案。
怎么按照筛选策略排序呢?
对于一条筛选,在结构体中申请元素表示该筛选条件满不满足,如果满足置为1,否则为0。在重载小于号时,按照该元素从大到小排序。这样满足该条件的就放到了前面,不满足的就在后面。

#include<bits/stdc++.h>
using namespace std;#define Ios ios::sync_with_stdio(false),cin.tie(0)const int N = 200010, mod = 1e9+7;
int T, n, m;//队伍结构体
struct node{int cnt;int tan, gong, zhi;
}dui[N];//方案结构体
struct ST{int ou[7]; //第一组的所有队伍 int ya[7]; //第二组的所有队伍 int cnt1, cnt2; //两组的队伍个数 int zg; //指挥官和工兵都有 int zhi; //有指挥官 int cha; //两组人数之差 int tan; //有坦克 int more; //是否第一组比第二组人多 friend bool operator < (ST a, ST b){if(a.tan != b.tan) return a.tan > b.tan; //筛选条件0 if(a.zg != b.zg) return a.zg > b.zg; //条件1if(a.zhi != b.zhi) return a.zhi > b.zhi; //2if(a.cha != b.cha) return a.cha < b.cha; //3if(a.more != b.more) return a.more > b.more; //4 for(int i=1;i<=min(a.cnt1, b.cnt1);i++) //5if(a.ou[i] != b.ou[i]) return a.ou[i] < b.ou[i];}
}a[N];signed main(){Ios;for(int i=1;i<=6;i++) cin >> dui[i].cnt;for(int i=1;i<=6;i++){string s; cin >> s;if(s[0] == '1') dui[i].tan = 1;if(s[1] == '1') dui[i].gong = 1;if(s[2] == '1') dui[i].zhi = 1;}for(int i=0;i<64;i++) //二进制枚举所有分配方案{int cnt1=0, cnt2=0;int sum1 = 0, sum2 = 0;for(int j=1;j<=6;j++) //每一位的01对应分配{if((i >> j-1) & 1){if(dui[j].cnt) a[i].ou[++cnt1] = j, sum1 += dui[j].cnt;}else{if(dui[j].cnt) a[i].ya[++cnt2] = j, sum2 += dui[j].cnt;}}a[i].cnt1 = cnt1;a[i].cnt2 = cnt2;int tan1 = 0, tan2 = 0, zhi1 = 0, zhi2 = 0, gong1 = 0, gong2 = 0;for(int j=1;j<=cnt1;j++){int x = a[i].ou[j];if(dui[x].tan) tan1 = 1;if(dui[x].zhi) zhi1 = 1;if(dui[x].gong) gong1 = 1;}for(int j=1;j<=cnt2;j++){int x = a[i].ya[j];if(dui[x].tan) tan2 = 1;if(dui[x].zhi) zhi2 = 1;if(dui[x].gong) gong2 = 1;}if(tan1 && tan2) a[i].tan = 1;if(zhi1 && zhi2 && gong1 && gong2) a[i].zg = 1;if(zhi1 && zhi2) a[i].zhi = 1;a[i].cha = abs(sum1 - sum2);if(sum1 > sum2) a[i].more = 1;}sort(a, a+64); //将所有方案按照给定的筛选条件排序ST ans = a[0]; //首个元素便是最优方案 if(!ans.tan){cout << "GG";return 0;}for(int i=1;i<=ans.cnt1;i++){cout << ans.ou[i];if(i!=ans.cnt1) cout << " ";}cout << endl;for(int i=1;i<=ans.cnt2;i++){cout << ans.ya[i];if(i!=ans.cnt2) cout << " ";}return 0;
}

然后还有一个方法就是,一点一点循环判断,如果方案唯一就退出,否则就执行下一条筛选…
写的比较多,比较烦。
而且还不知道为什么有一个点过不去。

#include<bits/stdc++.h>
using namespace std;const int N = 100010;
int n, m;
struct node{int cnt;int mt, bing, zhihui;
}a[N];
int x[N], y[N];
int cntx, cnty;
int cnt;
vector<int> ans[N][2];
int f[N];void pd()
{int flag = 0;for(int i=1;i<=cntx;i++){int idx = x[i];if(a[idx].mt) flag = 1;}if(!flag) return;flag = 0;for(int i=1;i<=cnty;i++){int idx = y[i];if(a[idx].mt) flag = 1;}if(!flag) return;cnt++;for(int i=1;i<=cntx;i++) ans[cnt][0].push_back(x[i]);for(int i=1;i<=cnty;i++) ans[cnt][1].push_back(y[i]);
}void dfs(int u)
{if(u==7){pd();return;}x[++cntx] = u;dfs(u+1);cntx--;y[++cnty] = u;dfs(u+1);cnty--;
}bool Less(vector<int> v1, vector<int> v2)
{int m = min(v1.size(), v2.size());for(int i=0;i<m;i++){if(v1[i] < v2[i]) return 1;else if(v1[i] > v2[i]) return 0;}
}int main()
{for(int i=1;i<=6;i++) cin >> a[i].cnt;for(int i=1;i<=6;i++){string s; cin >> s;if(s[0]=='1') a[i].mt = 1;if(s[1]=='1') a[i].bing = 1;if(s[2]=='1') a[i].zhihui = 1;}dfs(1);//1 int sum = 0, ansi = 0;for(int i=1;i<=cnt;i++){vector<int> v1 = ans[i][0];vector<int> v2 = ans[i][1];int flag1 = 0, flag2 = 0;for(int x : v1){if(a[x].zhihui) flag1 = 1;if(a[x].bing) flag2 = 1;}if(!flag1 || !flag2){f[i] = 1;continue;}flag1 = 0, flag2 = 0;for(int x : v2){if(a[x].zhihui) flag1 = 1;if(a[x].bing) flag2 = 1;}if(!flag1 || !flag2){f[i] = 1;continue;}sum ++;ansi = i;}if(sum == 1){vector<int> v1 = ans[ansi][0];vector<int> v2 = ans[ansi][1], res1, res2;for(int i=0;i<v1.size();i++){int x = v1[i];if(a[x].cnt) res1.push_back(x);}for(int i=0;i<v2.size();i++){int x = v2[i];if(a[x].cnt) res2.push_back(x);}for(int i=0;i<res1.size();i++){cout << res1[i];if(i!=res1.size()-1) cout << " ";}cout << endl;for(int i=0;i<res2.size();i++){cout << res2[i];if(i!=res2.size()-1) cout << " ";}return 0;}if(sum == 0){for(int i=1;i<=cnt;i++) f[i] = 0;//2sum = 0;for(int i=1;i<=cnt;i++){vector<int> v1 = ans[i][0];vector<int> v2 = ans[i][1];int flag1 = 0, flag2 = 0;for(int x : v1){if(a[x].zhihui) flag1 = 1;}if(!flag1){f[i] = 1;continue;}flag1 = 0, flag2 = 0;for(int x : v2){if(a[x].zhihui) flag1 = 1;}if(!flag1){f[i] = 1;continue;}sum ++;ansi = i;}if(sum == 1){vector<int> v1 = ans[ansi][0];vector<int> v2 = ans[ansi][1], res1, res2;for(int i=0;i<v1.size();i++){int x = v1[i];if(a[x].cnt) res1.push_back(x);}for(int i=0;i<v2.size();i++){int x = v2[i];if(a[x].cnt) res2.push_back(x);}for(int i=0;i<res1.size();i++){cout << res1[i];if(i!=res1.size()-1) cout << " ";}cout << endl;for(int i=0;i<res2.size();i++){cout << res2[i];if(i!=res2.size()-1) cout << " ";}return 0;}if(sum == 0){for(int i=1;i<=cnt;i++)f[i] = 0;}}//3sum = 0, ansi = 0;int maxa = 1e9;for(int i=1;i<=cnt;i++){if(f[i]) continue;vector<int> v1 = ans[i][0];vector<int> v2 = ans[i][1];int sum1 = 0, sum2 = 0;for(int x : v1){sum1 += a[x].cnt;}for(int x : v2){sum2 += a[x].cnt;}if(abs(sum1 - sum2) < maxa){maxa = abs(sum1 - sum2);ansi = i;sum = 1;}else if(abs(sum1 - sum2) == maxa){sum ++;}}if(sum == 1){vector<int> v1 = ans[ansi][0];vector<int> v2 = ans[ansi][1], res1, res2;for(int i=0;i<v1.size();i++){int x = v1[i];if(a[x].cnt) res1.push_back(x);}for(int i=0;i<v2.size();i++){int x = v2[i];if(a[x].cnt) res2.push_back(x);}for(int i=0;i<res1.size();i++){cout << res1[i];if(i!=res1.size()-1) cout << " ";}cout << endl;for(int i=0;i<res2.size();i++){cout << res2[i];if(i!=res2.size()-1) cout << " ";}return 0;}sum = 0, ansi = 0;for(int i=1;i<=cnt;i++){if(f[i]) continue;vector<int> v1 = ans[i][0];vector<int> v2 = ans[i][1];int sum1 = 0, sum2 = 0;for(int x : v1){sum1 += a[x].cnt;}for(int x : v2){sum2 += a[x].cnt;}if(abs(sum1 - sum2) != maxa) f[i] = 1;}//4sum = 0, ansi = 0, maxa = 1e9;for(int i=1;i<=cnt;i++){if(f[i]) continue;vector<int> v1 = ans[i][0];vector<int> v2 = ans[i][1];int sum1 = 0, sum2 = 0;for(int x : v1){sum1 += a[x].cnt;}for(int x : v2){sum2 += a[x].cnt;}if(sum1 <= sum2) f[i] = 1;else{sum++;ansi = i;}}if(sum == 1){vector<int> v1 = ans[ansi][0];vector<int> v2 = ans[ansi][1], res1, res2;for(int i=0;i<v1.size();i++){int x = v1[i];if(a[x].cnt) res1.push_back(x);}for(int i=0;i<v2.size();i++){int x = v2[i];if(a[x].cnt) res2.push_back(x);}for(int i=0;i<res1.size();i++){cout << res1[i];if(i!=res1.size()-1) cout << " ";}cout << endl;for(int i=0;i<res2.size();i++){cout << res2[i];if(i!=res2.size()-1) cout << " ";}return 0;}vector<int> t;for(int i=1;i<=10;i++) t.push_back(1e9);sum = 0, ansi = 0, maxa = 1e9;for(int i=1;i<=cnt;i++){if(f[i]) continue;vector<int> v1 = ans[i][0];if(Less(v1, t)){t = v1;sum = 1;ansi = i;}}if(sum == 1){vector<int> v1 = ans[ansi][0];vector<int> v2 = ans[ansi][1], res1, res2;for(int i=0;i<v1.size();i++){int x = v1[i];if(a[x].cnt) res1.push_back(x);}for(int i=0;i<v2.size();i++){int x = v2[i];if(a[x].cnt) res2.push_back(x);}for(int i=0;i<res1.size();i++){cout << res1[i];if(i!=res1.size()-1) cout << " ";}cout << endl;for(int i=0;i<res2.size();i++){cout << res2[i];if(i!=res2.size()-1) cout << " ";}return 0;}cout << "GG";return 0;
}

经验
场上dfs搜出所有方案之后,一步一步循环判断,如果找到唯一解就退出,否则进入下一条继续判断…写了半个多钟头没写完,发现样例都没跑出来,然后就没有勇气往下接写了,直接去看下一题了。。
加上存储所有方案用vector存的,后面判断也写的有点烦。
应该想清楚后面应该怎么接着处理,再选择合适的方式来存放数据。免得后面就很麻烦。


RC-u5 树与二分图

题意
给定一个 n n n 节点的树,问有多少个点对 ( i , j ) (i, j) (i,j) 满足:

  • 树中节点 i i i 和 j j j 之间没有边直接相连;
  • 将无向边 ( i , j ) (i, j) (i,j) 加上之后整个树能构成二分图。

2 ≤ N ≤ 1 0 6 2≤N≤10^6 2≤N≤106

思路
要知道,一棵树本来就是一个二分图:根节点确定之后,深度为奇数的点在一个集合,深度为偶数的点在另一集合。

那么现在要连接两个节点,连接之后还要满足二分图,那肯定是深度为奇数的点向深度为偶数的点连边,或者深度为偶数的点向深度为奇数的点连边。

那么就可以从上到下遍历每一个节点,其和之前遍历过的深度奇偶性不同的所有点连边。因为要满足连边前两节点不直接相连,所以其父节点要去掉,点数-1。

或者记录每一层有多少节点,对于每一层来说,这一层的节点数 *(之前奇偶性不同层数的节点数-1)便是这一层的节点和上面节点连边的方案数。每一层这样的方案数相加便是总的方案数。

Code

#include<bits/stdc++.h>
using namespace std;const int N = 1000010;
int n, m;
int a[N];
vector<int> e[N];
int f[N], flor[N];void bfs()
{queue<int> que;que.push(1);f[1] = 1;a[1] = 1;while(que.size()){int x = que.front(); que.pop();for(int tx : e[x]){if(f[tx]) continue;f[tx] = 1;flor[tx] = flor[x] + 1;a[flor[tx]] ++;que.push(tx);}}
}int main(){cin >> n;for(int i=1;i<n;i++){int x, y;cin >> x >> y;e[x].push_back(y);e[y].push_back(x);}flor[1] = 1;bfs();long long cnt0 = 0, cnt1 = 0;long long ans = 0;for(int i=1;i<=n;i++){if(i%2) cnt1 += a[i];else cnt0 += a[i];if(i%2){if(a[i] && cnt0) ans += a[i]*(cnt0-1);}else if(a[i] && cnt1) ans += a[i]*(cnt1-1);}cout << ans;return 0;
}

T4 写了半个多钟头没有结果,样例都跑不出来就没有勇气继续写了,先去看了最后一题。看到二分图,又觉得是最后一题,应该很难吧,所以就直接暴力跑了个染色法判定拿了个暴力分。。都没有继续往下想。。
回过头来看 T4 也不想写了。。

继续训练吧!

2022 RoboCom 世界机器人开发者大赛-本科组(省赛)T4, T5相关推荐

  1. 2022 RoboCom 世界机器人开发者大赛-本科组(省赛)挨打记录

    总结: 在pintia平台做题千万得早点做会的题,要不然等到最后全是疯狂提交撞数据骗分的,最后五分钟,提交一次题要等前面6900多人,根本来不及. 多看板子少摸鱼 学校实验室是真滴爽 做题连接 登录签 ...

  2. 2022 RoboCom 世界机器人开发者大赛-本科组(省赛) CAIP 完整版题解

    文中代码均可AC, 有任何问题欢迎在评论区留言讨论 文章目录 RC-u1 不要浪费金币 题解 AC代码 RC-u2 智能服药助手 题解 AC代码(带注释) RC-u3 跑团机器人 题解 AC代码(详细 ...

  3. 2022 RoboCom 世界机器人开发者大赛-本科组(省赛)-- 第三题 跑团机器人 (已完结)

    其它题目 题目 RC-u3 跑团机器人 在桌面角色扮演游戏(TRPG,俗称"跑团")中,玩家需要掷出若干个骰子,根据掷出的结果推进游戏进度.在线上同样可以跑团,方法是由玩家们向机器 ...

  4. 2022 RoboCom 世界机器人开发者大赛-本科组(省赛)

    文章目录 1.不要浪费金币 2.智能服药助手 3.跑团机器人 4.攻略分队 5.树与二分图 1.不要浪费金币 哲哲最近在玩一个游戏,击杀怪物能获得金币 -- 这里记击杀第 i 个怪物获得的金币数量为 ...

  5. 2022 RoboCom 世界机器人开发者大赛-本科组(省赛)RC-u4 攻略分队 (已完结)

    其它题目 题目 RC-u4 攻略分队 副本是游戏里的一个特色玩法,主要为玩家带来装备.道具.游戏资源的产出,满足玩家的游戏进程. 在 MMORPG<最终幻想14>里,有一个攻略人数最大达到 ...

  6. 2022 RoboCom 世界机器人开发者大赛-本科组(国赛)

    文章目录 1.智能红绿灯 2.女王的大敕令 3.战利品分配 4.变牛的最快方法 5.养老社区 1.智能红绿灯 为了最大化通行效率同时照顾老年人穿行马路,在某养老社区前,某科技公司设置了一个智能红绿灯. ...

  7. 2022 RoboCom 世界机器人开发者大赛-本科组(省赛)-- 第五题 树与二分图 (已完结)

    其它题目 题目 RC-u5 树与二分图 设 G=(V,E) 是一个无向图,如果顶点集合 V 可分割为两个互不相交的子集 (A,B),并且每条边 (i,j)∈E 的两个端点 i 和 j 分别属于这两个不 ...

  8. 2022 RoboCom 世界机器人开发者大赛-本科组(国赛)-- 第三题 RC-u3 战利品分配

    在某个战争游戏中,多个玩家组成一个大型军团,攻下若干城池,并获得战利品. 具体而言,游戏中有 N 个城市,并以 M 条长度为 1 的无向道路连接,玩家们组成的军团从 S 号城市开始进攻,目的地是 T  ...

  9. 2022 RoboCom 世界机器人开发者大赛-高职组 国赛(RC-v3 智能护理中心统计)

    RC-v3 智能护理中心统计 题意: 给出各管理节点的关系,和每个管理节点的照护老人数量. 两种操作:1. 转院. 2. 查询 该管理节点以下总的老人人数. 知识点: 树. #include<b ...

最新文章

  1. 游戏打包过程枯燥且繁琐,如何提升打包效率?
  2. Springboot 通过Ftp协议下载文件,并在Vue平台上显示其内容
  3. libcareplus多补丁管理
  4. java opencv sift_Java opencv中sift的实现
  5. 新零售企业构建智慧营销体系
  6. 无模拟电路基础如何看TTL电路
  7. win10的计算机 桌面图标不见了怎么办,Win10我的电脑怎么放在桌面?Win10此电脑图标不见了的解决方法...
  8. Mac小技巧:五秒学会Mac电脑旋转屏幕
  9. 服务器维护封号,LOL客服的关于他们自己服务器问题导致账号被封号的问题
  10. Redis(设计与实现):28---事件之文件事件(AE_READABLE事件、AE_WRITABLE事件)
  11. 折叠屏市场起风,华为、OPPO“你追我赶”
  12. 在线检测计算机硬件信息,JS获取客户端计算机硬件信息与系统信息大全
  13. 微信小程序|小程序开发进阶
  14. LVS+Keeplive 负载均衡
  15. Spark——Spark概述
  16. sim900芯片—GPRS使用C语言接电话和收短信应用程序
  17. 4 年 Java 经验面试总结、心得体会(太全面了!!都会就无敌了)
  18. 5G前夜,TCL瞄准8K
  19. 赛宁网安携车联网、工控安全强势亮相网络安全宣传周
  20. 抛弃WinSCPnbsp;教你使用CuteFTP传输文件

热门文章

  1. android解密联想,Android 版茄子快传漏洞
  2. 华为云账号实名认证流程(材料及图文教程)
  3. android录制视频计时,Android实现微信录制小视频的计时动画
  4. 在ubuntu10.10, 打印机MFC-7340安装
  5. 华南理工大学计算机组成原理重点复习
  6. 虚拟直流电机_VDG_SIMULINK模型搭建详解
  7. 继 K3s 之后,又来个 K0s...
  8. WSingle主题 – 支持多本的WordPress小说主题,美观大方,功能强大
  9. [Python工具]anaconda 使用
  10. 地铁供电系统原理图_策划|5分钟读懂地铁运行原理