20180415校赛
A - Meopass And ToRapture
Problem Description
meopass和ToRapture玩游戏,有n堆石子,每堆石子有ai的重量。
两人轮流行动,ToRapture先手。每次ToRapture会拿若干堆总重量为奇数的的石子,而meopass会拿若干堆总重量为偶数的的石子,两个人都会采取最优行动策略,无法行动的人输。
meopass花了10分钟(天)完全了解这个游戏了,他知道了这个游戏的必胜方法,于是他自己带了很多很多的石子,想要在游戏开始前作弊,通过选取一些堆,在上面添加一些自己带来的石子,从而保持自己的必胜。
问他最少需要带多少石子才能保证自己的胜利?
Input
共T次询问,每组样例第一行包含正整数
T=10,1≤n≤106,1≤ai≤109
Output
对于每次询问输出一个答案,每个答案占一行。
Sample Input
1
2
2 1
Sample Output
1
Manager
meopass
只要堆里面有一个是奇数那么一定可以组成奇数个,meopass需要把所有奇数补成偶数
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin>>t;
while(t--) {
int n;
cin>>n;
int cnt=0;
for(int i=1; i<=n;i++) {
int v;
cin>>v;
if(v&1) cnt++;
}
cout<<cnt<<endl;
}
return 0;
}
<br ><br >
<br >
B - Secret Space
<br >
Problem Description
meopass在101一不小心睡着了。
睡梦中的他进入了一个美丽的三维空间,空间里有n个旅游景点,他们的位置为(xi,yi,zi ),景点间的距离是欧氏距离(欧几里得距离,例如二维的欧氏距离就是勾股定理)。但是这n个景点都是独立的,空间的主人希望他建一些桥梁,从而把这n个景点连接起来,不然就永远把他囚禁在这里。每个桥梁连接两个不同的景点,桥梁的造价就是这两个景点间的距离。
问他需要花费的最少价钱是多少,因为花的太多的话空间的主人就会不高兴了QAQ。
Input
共T次询问,每组样例第一行包含正整数n,含义如上。
T=5,1≤n≤1000, −1000≤xi,yi,zi≤1000
Output
对于每次询问输出一个答案,每个答案占一行,保留小数点后两位有效数字。
Sample Input
1
2
1 1 1
2 2 2
Sample Output
1.73
<br ><br ><br >
三维空间下的最小生成树问题,
我们只需要O(n^2)处理出任意两点之间的距离就成了一个最小生成树的裸题...
prim由于要用到邻接矩阵,所以稠密图比较合适,kruskal要对所有的边排序,因此稀疏图比较合适。。然而我又不能判断谁稠密谁稀疏,这道题两个都能过
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1111;
const int inf =0x3f3f3f;
double cost[maxn][maxn];
double mc[maxn];
bool used[maxn];
int v;
int vv;
void init()
{
for(int i=0;i<maxn;i++){
used[i]=0;
mc[i]=0;
}
}
struct ss
{
int x;
int y;
int z;
}a[maxn];
double prim ()
{
for(int i = 0;i<vv;i++){
mc[i] = inf;
used[i]=false;
}
mc[0] = 0;
double res = 0;
while(true){
int v = -1;
for(int u=0;u<vv;u++){
if (!used[u]&&(v==-1||mc[u]<mc[v]))
v = u;
}
if(v ==-1 ) break;
used[v] =true;
res += mc[v];
for (int u = 0;u<vv;u++)
mc[u] = min(mc[u],cost[v][u]);
}
return res;
}
double suan(double a)
{
return (abs(a*a));
}
int main ()
{
int t;
cin >> t;
while(t--)
{
init();
int n ;
cin >> n;
for(int i = 0;i<n;i++)
cin >> a[i].x>>a[i].y >>a[i].z;
vv = n;
for(int i =0;i<n;i++){
for(int j= 0;j<n;j++){
if(i!=j)
cost[i][j] = sqrt(suan(a[i].x-a[j].x)+suan(a[i].y-a[j].y)+suan(a[i].z -a[j].z));
else
cost [i][j] =inf ;
}
}
//cout << prim() <<endl;
double ans = prim();
printf("%.2f\n",ans);
}
}
C - Hearth Rare Stone
Problem Description
axp非常喜欢一款技术性超强的抽卡赌博游戏,它改编自知名牌类游戏比大小。游戏开始时牌库中有30张卡牌,开局先从牌库中抽3张牌,之后每回合可以抽一张牌(也就是说第一回合开始时,你实际上起了3+1=4张牌),然后再出一张牌。
牌库中有两种牌,每张牌都有一个价值:1.随从牌,价值为v(1≤v≤1000),使用一张价值为v的卡牌会为你召唤一名随从,每回合这个随从都可以攻击敌人一次造成v点伤害。在召唤出随从后,这名随从不能立刻攻击,需要等到下回合才可以第一次攻击敌人。2.一种神奇的卡牌“右手第一张”。这种卡牌的价值为0,但使用这张卡牌之后,你会情不自禁地向敌人致敬:“抱歉”,同时直接对敌人造成1000点伤害。
现在axp和meopass要在这款游戏中一决高下。axp担心会惨败,于是开了透视外挂看穿了牌库中的30张牌。
请你帮axp制定出牌策略,使得meopass受到尽量多的伤害。
Input
第一行一个整数T,代表数据组数。
接下T组数据,每组数据一行30个数,其中第i个数代表牌库中第i张卡牌的价值。
输入保证合法。
Output
40回合后axp对meopass造成的伤害总和。
什么,你问卡抽完了怎么办?继续打呗=v=
每组数据输出一行,包含一个整数作为答案。
Sample Input
3
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
Sample Output
29039
735
29013
Hint
样例1:第一回合打出价值为1的随从牌,之后29回合每回合打出一张“右手第一张”,40回合共计造成伤害139+291000=29039
Manager
axp
思路超级明显啊,明显的贪心,可自己代码能力很差的样子实现起来很困难 > . < 其实实现起来很简单啊
看到陈聚聚博客用优先队列做的很好的思路啊...copy 一下供自己学习喵
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 1<<30;
const int md = 1e9+7;
int T;
int ans;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
cin>>T;
while(T--){
ans=0;
int x;
priority_queue<int> q;
int n=30;
for(int i=1;i<=3;i++){
cin>>x;
q.push(x);
n--;
if(x==0)ans+=1000;
}
int now =0;
for(int i=1;i<=40;i++){
if(n){
cin>>x;
q.push(x);
n--;
if(x==0)ans+=1000;
}
ans+=now;
if(!q.empty()){
now+=q.top();
q.pop();
}
}
cout<<ans<<endl;
}
return 0;
}
D - ToRapture And Golang Package
Problem Description
ToRapture在学习编程的时候发现Golang的package之间不能循环依赖。 例如在Golang中,若package A依赖package B,package B又依赖package A,则无法构建项目。 给出若干package之间的依赖关系,请你判断出能否成功构建项目。
Input
多组输入,每组的第一行为两个非负整数N,MN,M,表示共有NN个package和MM条依赖关系, 接下来的一行为NN个只由大小写字母组成的互不相同的字符串p1,p2⋯pn,每个字符串pi最多16个字符,字符串间用空格分割。 接下来的M行,每行两个字符串pi,pj,表示pi依赖pj。∑N≤105,∑M≤5×105
Output
对于每组数据,若可以成功构建,即没有循环依赖,则输出一行"Citrus Saikou!",否则输出一行"DameDameYo",输出双引号内的内容。
Sample Input
4 5
mei yuzu matsuri harumi
mei yuzu
harumi yuzu
harumi mei
matsuri mei
matsuri harumi
5 4
A B C D E
B A
C A
D B
E C
3 1
str os sys
os str
4 4
socket redis kv data
redis socket
kv redis
data kv
redis data
Sample Output
Citrus Saikou!
Citrus Saikou!
Citrus Saikou!
DameDameYo
拓扑排序裸题,一开始自己不好好读题,第一反应并查集判树???并不 可是连通又不代表依赖什么的,首先要明确这是有个有向图,还是对图论理解不是太深刻啊呜呜呜
自己调bug调好久原因是局部变量覆盖了全局变量... 好蠢多组输入时候初始化还是要多注意啊
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5+10;
vector<int> vec[maxn];
vector <int>::iterator it;
map<string,int>mp;
int ine[maxn];
int t,u,v,n,m,id;
void init()
{
mp.clear();
for(int i=0;i<maxn;i++)
vec[i].clear(),ine[i]=0;
id = 1;
}
void tuop(){
int cur,cnt =0;
queue<int>que;
for(int i=1; i<=n; i++)
if(!ine[i]) que.push(i);
while(!que.empty())
cur = que.front();
que.pop();
cnt++;
for(it=vec[cur].begin(); it!=vec[cur].end(); it++){
int tmp = *it;
ine[tmp] --;
if(ine[tmp]==0)
que.push(tmp);
}
}
if(cnt!=n)
cout<<"DameDameYo"<< endl;
else
cout << "Citrus Saikou!"<<endl;
}
int main( )
{
while (cin >> n >> m){
init();
for(int i=0; i<n; i++){
string s;
cin >> s;
mp[s]=id;
id ++;
}
for(int i =0; i<m; i++){
string a,b;
cin >> a >> b;
vec[mp[a]].push_back(mp[b]);
++ine[mp[b]];
}
tuop();
}
return 0;
}
E I是两道水题
代码写的不好但是还是直接贴代码了反正不会有人看到233333
E题写的真的很啰嗦 大概是赛场上大脑缺氧吧 或者说自己思维真的不好
没过的题以后再补..我会好好补的..
总之表现真的很差很差很差 .. 好好训练.
#include <bits/stdc++.h>
using namespace std;
string r ="Red";
string y="Yellow";
string g="Green";
int main ()
{
int t;
cin >> t;
while(t--){
int cntr = 0;
int cnty = 0;
int cntg = 0;
int n;
cin >> n;
for(int i =0; i<n; i++){
string s;
cin >> s;
for(int i=0 ; i<s.size(); i++){
if(s[i]=='R') cntr++;
if(s[i]=='G') cntg++;
if(s[i]=='Y') cnty++;
}
}
//cout<<cntr<<cntg<<cnty<<endl;
int maxx = max(cntr,cntg);
int maxx2 =max(maxx,cnty);
if(cntr==maxx2&&cntg!=maxx2&&cnty!=maxx2)
cout<<r<<endl;
if(cnty==maxx2&&cntr!=maxx2&&cntg!=maxx2)
cout<<y<<endl;
if(cntg==maxx2&&cntr!=maxx2&&cnty!=maxx2)
cout<<g<<endl;
if(cntg==maxx2&&cntr==maxx2&&cnty!=maxx2)
cout<<g<<' '<<r<<endl;
if(cntg==maxx2&&cntr!=maxx2&&cnty==maxx2)
cout<<g<<' '<<y<<endl;
if(cntg!=maxx2&&cntr==maxx2&&cnty==maxx2)
cout<<r<<' '<<y<<endl;
if(cntg==maxx2&&cntr==maxx2&&cnty==maxx2)
cout<<g<<' '<<r<<' '<<y<<endl;
}
return 0;
}
F题WA了一次又是输入多组数据的原因
tolower是在紫书上看到的 紫书思维真的都是超级棒的
快回去好好写紫书喵
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int cnt[30];
string s;
void init()
{
for(int i =0; i<29; i++)
cnt[i]=0;
}
int main ()
{
while(cin>>s)
{
init();
// init();
int src = 26;
for(int i=0; i<s.size(); i++)
s[i] = tolower(s[i]);
for(int i= 0; i<s.size(); i++)
cnt[s[i]-'a']++;
sort(cnt,cnt+26);
// for(int i=25; i>=0; i--)
// cout<<cnt [i] <<'\t';
ll sum = 0;
//cout <<sum <<endl;
for(int i=25; i>=0; i--){
sum+=cnt[i]*src;
src--;
}
cout << sum <<endl;
// cout<<26*5+25+24 <<endl;
}
return 0
}