Wannafly summer camp Day2
问题 A: Tobaku Mokushiroku Kaiji
时间限制: 1 Sec 内存限制: 128 MB
题目描述
Kaiji正在与另外一人玩石头剪刀布。双方各有一些代表石头、剪刀、布的卡牌,每局两人各出一张卡牌,根据卡牌的内容决定这一局的胜负。胜负规则为:石头赢剪刀、剪刀赢布、布赢石头、相同为平局。每张卡牌至多被使用一次。
已知双方的卡牌数量,问Kaiji最多赢几局?
已知双方的卡牌数量,问Kaiji最多赢几局?
输入
一行六个数字0≤a,b,c,d,e,f≤50,a,b,c分别表示Kaiji的石头、剪刀、布的牌的数量,d,e,f分别表示此时另一人的石头、剪刀、布的牌的数量。
输出
一个整数表示Kaiji最多赢几局。
样例输入
29 7 41 14 12 42
样例输出
33
水题
#include <bits/stdc++.h> #define maxn 100005 using namespace std; typedef long long ll; int main() { int a,b,c,d,e,f; cin>>a>>b>>c>>d>>e>>f; int ans=min(a,e)+min(b,f)+min(c,d); printf("%d\n",ans); }
问题 B: Utawarerumono
题目描述
算术是为数不多的会让久远感到棘手的事情。通常她会找哈克帮忙,但是哈克已经被她派去买东西了。于是她向你寻求帮助。
给出一个关于变量x,y的不定方程ax+by=c,显然这个方程可能有多个整数解。久远想知道如果有解,使得p2*x2+p1*x+q2*y2+q1*y最小的一组整数解是什么。为了方便,你只需要输出p2*x2+p1*x+q2*y2+q1*y的最小值。
给出一个关于变量x,y的不定方程ax+by=c,显然这个方程可能有多个整数解。久远想知道如果有解,使得p2*x2+p1*x+q2*y2+q1*y最小的一组整数解是什么。为了方便,你只需要输出p2*x2+p1*x+q2*y2+q1*y的最小值。
输入
第一行三个空格隔开的整数a,b,c(0≤a,b,c≤105)。
第二行两个空格隔开的整数p1,p2(1≤p1,p2≤105)。
第三行两个空格隔开的整数q1,q2(1≤q1,q2≤105)。
第二行两个空格隔开的整数p1,p2(1≤p1,p2≤105)。
第三行两个空格隔开的整数q1,q2(1≤q1,q2≤105)。
输出
如果方程无整数解,输出"Kuon"。
如果有整数解,输出p2*x2+p1*x+q2*y2+q1*y的最小值。
如果有整数解,输出p2*x2+p1*x+q2*y2+q1*y的最小值。
样例输入
2 2 1
1 1
1 1
样例输出
Kuon
使用扩展欧几里得计算出x,y的通解。容易发现,当x,y较大时,x^x与y^y占主导。枚举x,y,但需要卡住一个范围,让所求值不爆longlong.
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll ex_gcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0; return a; } ll ans=ex_gcd(b,a%b,x,y); ll temp=x; x=y; y=temp-(a/b)*x; return ans; } int main() { ll a,b,c; //freopen("in.txt","w",stdout); ll p1,p2,q1,q2; cin>>a>>b>>c>>p1>>p2>>q1>>q2; ll x,y; if(a==0&&b==0&&c==0) { printf("0\n"); return 0; } if(a==0&&b==0&&c!=0) { printf("Kuon\n"); return 0; } if(a==0||b==0) { if(a==0) { if(c%b==0) { ll y=c/b; ll ans=q2*y*y+q1*y; ll temp= -p1/(2*p2); //ll tmpp=temp*temp*p2+p1*temp; //ans+=tmpp; printf("%lld\n",ans); } else if(c%b!=0) { printf("Kuon\n"); } } else { if(c%a==0) { ll x=c/a; ll ans=p1*x*x+p1*x; ll temp= -q1/(2*q2); //ll tmpp=temp*temp*q2+q1*temp; //ans+=tmpp; printf("%lld\n",ans); } else if(c%a!=0) { printf("Kuon\n"); } } return 0; } ll g=ex_gcd(a,b,x,y); if(c%g!=0) { printf("Kuon\n"); } else { ll d=c/g; x*=d,y*=d; x=(x%b+b)%b; y=(c-a*x)/b; a/=g,b/=g,c/=g; ll ans=p2*x*x+p1*x+q2*y*y+q1*y; ll xx=x,yy=y; ll f1=sqrt((ll)4e18/p2); ll f2=sqrt((ll)4e18/p1); for(ll i=1;i<=1e6;i++) { x+=b; y-=a; //printf("%lld %lld\n",x,y); if(abs(x)>1e6+10) break; if(abs(y)>1e6+10) break; ll temp=p2*x*x+p1*x+q2*y*y+q1*y; ans=min(temp,ans); } for(int i=1;i<=1e6;i++) { xx-=b; yy+=a; //printf("%lld %lld\n",xx,yy); if(abs(xx)>1e6+10) break; if(abs(yy)>1e6+10) break; ll temp=p2*xx*xx+p1*xx+q2*yy*yy+q1*yy; ans=min(temp,ans); } printf("%lld\n",ans); } return 0; }
问题 D: Eustia of the Tarnished Wings
题目描述
Novus Aither是一个潜藏着多个势力的城市。每个势力都有一个唯一的领导人,每个领导人有一个属性值。如果两个势力的领导人的属性值分别为a,b,且∣a−b∣≤m,说明这两个领导人的思想有一定的相似之处,这两个势力可以合并,新的领导人可以指定为原来的两个领导人中的任意一个。
问在所有可能的情况中,最少会剩下几个势力。
问在所有可能的情况中,最少会剩下几个势力。
输入
第一行两个空格隔开的整数n(1≤n≤106),m(0≤m≤109)。n代表当前势力的个数。m的含义如题目描述。
第二行n个空格隔开的整数di(0≤di≤109),代表第i个势力的领导人的属性值。
第二行n个空格隔开的整数di(0≤di≤109),代表第i个势力的领导人的属性值。
输出
输出一个数表示势力的最少数量。
样例输入
4 1
2 1 3 10
样例输出
2
对能力排序,从小到大往上合并,如果能合并,cnt++。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e6 + 5; int a[maxn]; int main() { // freopen("in.txt", "r", stdin); int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; ++i) scanf("%d", &a[i]); sort(a, a + n); int cnt = n; for (int i = 1; i <= n; ++i) if (abs(a[i] - a[i - 1]) <= m) --cnt; printf("%d\n", cnt); return 0; }
问题 H: Princess Principal
题目描述
阿尔比恩王国(the Albion Kingdom)潜伏着一群代号“白鸽队(Team White Pigeon)”的间谍。在没有任务的时候,她们会进行各种各样的训练,比如快速判断一个文档有没有语法错误,这有助于她们鉴别写文档的人受教育程度。
这次用于训练的是一个含有n个括号的文档。括号一共有mm种,每种括号都有左括号和右括号两种形式。我们定义用如下的方式定义一个合法的文档:
1.一个空的字符串是一个合法的文档。
2.如果A,B都是合法的文档,那么AB也是合法的文档。
3.如果S是合法的文档,那么aSb也是合法的文档,其中a,b是同一种括号,并且a是左括号,b是右括号。
现在给出q个询问,每次询问只考虑文档第ll至rr个字符的情况下,文档是不是合法的。
这次用于训练的是一个含有n个括号的文档。括号一共有mm种,每种括号都有左括号和右括号两种形式。我们定义用如下的方式定义一个合法的文档:
1.一个空的字符串是一个合法的文档。
2.如果A,B都是合法的文档,那么AB也是合法的文档。
3.如果S是合法的文档,那么aSb也是合法的文档,其中a,b是同一种括号,并且a是左括号,b是右括号。
现在给出q个询问,每次询问只考虑文档第ll至rr个字符的情况下,文档是不是合法的。
这题感觉蛮难的啊,不知道为什么训练赛的时候那么多人A。
反正我到现在都只能勉强理解这个神仙做法。
首先我们考虑一个括号序列,它合法的条件是其区间内的所有括号序列。那么其实中间的这些括号是可以抵消的。
然后就可以O(n)预处理,每次处理的时候看栈是否为空,如果空的话,肯定是可行的。然后如果可以匹配,就弹出栈顶,并标记数组编号为之后栈顶的编号。
最后判断f[l-1]是否等于f[r]。
emmm可能说的不是很清楚,因为我自己也没怎么理解为什么能这样搞。
#include <bits/stdc++.h> #define maxn 1000005 using namespace std; stack<int> s; int a[maxn]; int f[maxn]; int main() { int n,m,q; scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=n;i++) { if(s.empty()) { s.push(i); f[i]=i; } else { if(a[s.top()]+1==a[i]&&a[i]%2==1) { s.pop(); if(s.empty()) f[i]=0; else f[i]=s.top(); } else { s.push(i); f[i]=i; } } } for(int i=1;i<=q;i++) { int l,r; scanf("%d%d",&l,&r); if(f[l-1]==f[r]) printf("Yes\n"); else printf("No\n"); } return 0; }
输入
第一行两个整数n,m,q(1≤n,m,q≤106)。
第二行有n个空格隔开的整数x,第i个整数xi(0≤xi<m∗2)代表文档中的第i个字符是第⌊x/2⌋种括号,且如果xi是偶数,它代表一个左括号,否则它代表一个右括号。
接下来q行,每行两个空格隔开的整数l,r(1≤l≤r≤n),代表询问第l至r个字符构成的字符串是否是一个合法的文档。
第二行有n个空格隔开的整数x,第i个整数xi(0≤xi<m∗2)代表文档中的第i个字符是第⌊x/2⌋种括号,且如果xi是偶数,它代表一个左括号,否则它代表一个右括号。
接下来q行,每行两个空格隔开的整数l,r(1≤l≤r≤n),代表询问第l至r个字符构成的字符串是否是一个合法的文档。
输出
输出共q行,如果询问的字符串是一个合法的文档,输出"Yes",否则输出"No"。
样例输入
6 4 3
0 2 3 1 4 7
1 4
1 5
5 6
样例输出
Yes
No
No
队友写的,待补。
问题 J: New Game
时间限制: 1 Sec 内存限制: 128 MB Special Judge
题目描述
Eagle Jump公司正在开发一款新的游戏。泷本一二三作为其员工,获得了提前试玩的机会。现在她正在试图通过一个迷宫。
这个迷宫有一些特点。为了方便描述,我们对这个迷宫建立平面直角坐标系。迷宫中有两条平行直线 L1:Ax+By+C1=0,L2:Ax+By+C2=0,还有 n 个圆 。角色在直线上、圆上、圆内行走不消耗体力。在其他位置上由S点走到T点消耗的体力为S和T的欧几里得距离。
泷本一二三想从L1出发,走到L2。请计算最少需要多少体力。
这个迷宫有一些特点。为了方便描述,我们对这个迷宫建立平面直角坐标系。迷宫中有两条平行直线 L1:Ax+By+C1=0,L2:Ax+By+C2=0,还有 n 个圆 。角色在直线上、圆上、圆内行走不消耗体力。在其他位置上由S点走到T点消耗的体力为S和T的欧几里得距离。
泷本一二三想从L1出发,走到L2。请计算最少需要多少体力。
输入
第一行五个正整数n,A,B,C1,C2(1≤n≤1000,−10000≤A,B,C1,C2≤10000),其中A,B 不同时为 0。
接下来 n 行每行三个整数x,y,r(−10000≤x,y≤10000,1≤r≤10000) 表示一个圆心为 (x,y),半径为 r 的圆。
接下来 n 行每行三个整数x,y,r(−10000≤x,y≤10000,1≤r≤10000) 表示一个圆心为 (x,y),半径为 r 的圆。
输出
仅一行一个实数表示答案。与标准答案的绝对误差或者相对误差不超过10-4即算正确。
样例输入
2 0 1 0 -4
0 1 1
1 3 1
样例输出
0.236068
把线看成点,到每个圆的距离为线到圆心的距离减去半径,两个圆之间距离为圆心间距离减两半径。
距离不能为负的,所以要对0取max
最后跑最短路即可。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e3 + 105; struct circle { double x,y,r; }a[maxn]; struct Edge { int v,next; double w; }edge[maxn*maxn*2]; int cnt; int head[maxn]; void addedge(int u,int v,double w) { edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } double dist[maxn]; void Dijstra(int s) { bool vis[maxn]={0}; priority_queue<pair<double,int>,vector<pair<double,int>>,greater<pair<double,int>>>q; for(int i=1;i<maxn;i++) dist[i]=-1; dist[s]=0; q.push(make_pair(dist[s],s)); while(!q.empty()) { int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=true; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; double w=edge[i].w; if((dist[v]==-1||dist[v]>dist[u]+w)&&!vis[v]) { dist[v]=dist[u]+w; q.push(make_pair(dist[v],v)); } } } } int main() { // freopen("in.txt", "r", stdin); int n; double x,y,c,d; memset(head,-1, sizeof(head)); scanf("%d%lf%lf%lf%lf",&n,&x,&y,&c,&d); for(int i=1;i<=n;i++) { scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].r); } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { double dd=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y))-a[i].r-a[j].r; dd=max(0.0,dd); addedge(i,j,dd); addedge(j,i,dd); } } for(int i=1;i<=n;i++) { double temp=fabs(x*a[i].x+y*a[i].y+c); double v=sqrt(x*x+y*y); double dd=temp/v-a[i].r; dd=max(dd,0.0); addedge(i,n+1,dd); addedge(n+1,i,dd); } for(int i=1;i<=n;i++) { double temp=fabs(x*a[i].x+y*a[i].y+d); double v=sqrt(x*x+y*y); double dd=temp/v-a[i].r; dd=max(dd,0.0); addedge(i,n+2,dd); addedge(n+2,i,dd); } double temp=fabs(c-d); double v=sqrt(x*x+y*y); double dd=temp/v; addedge(n+1,n+2,dd); addedge(n+2,n+1,dd); Dijstra(n+1); printf("%.6lf\n",dist[n+2]); return 0; }