A
Feeling is a drawing title ...
When the angle is too small, b and a + r when constitute a right triangle, \ (SiN W = B * (TH) + (a + r) * COS (TH) \) , or \ (w = \ sqrt {( a + r) ^ 2 + b ^ 2} \)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const double eps = 1e-8;
const double pi = acos(-1);
int main(){
int t; scanf("%d",&t);
double a,b,r,th;
while(t--){
scanf("%lf%lf%lf%lf",&a,&b,&r,&th);
th = th/180*pi;
double mp = sqrt((a+r)*(a+r)+b*b);
double t1 = asin(b/mp);
if(t1<=th){
printf("%.12lf\n",mp-r);
}else{
double si = sin(th),cs = cos(th);
printf("%.12lf\n",(a+r)*cs+b*si-r);
}
}
return 0;
}
D
Simulation title
- Ideas: find the law hive and connecting side to build map, then run the shortest path.
#include<bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
const int N = 1e3+10;
const int inf = 0x3f3f3f3f;
char ma[N*5][N*6];
int n,m,sp,tp;
struct E{
int v,nxt;
}e[N*N*100];
int head[N*N],tot,d[N*N];
void init(){
memset(head,-1,sizeof head); tot = 0;
}
void add(int u,int v){
e[tot] = (E){v,head[u]}; head[u] = tot++;
e[tot] = (E){u,head[v]}; head[v] = tot++;
}
int toid(int x,int y){
return (x-1)*m+y;
}
int dij(){
fill(d,d+1+n*m,inf);
priority_queue<pii,vector<pii>,greater<pii> > que;
d[sp] = 0; que.push(pii(0,sp));
while(que.size()){
pii p = que.top(); que.pop();
int u = p.second;
if(d[u]<p.first) continue;
for(int i=head[u];~i;i=e[i].nxt){
int v = e[i].v;
if(d[v] > d[u]+1){
d[v] = d[u] + 1;
que.push(pii(d[v],v));
}
}
}
return d[tp];
}
int main(){
int t; scanf("%d",&t);
char ch;
while(t--){
init();
scanf("%d%d",&n,&m);
getchar();
for(int i=1;i<=n*4+3;++i){
int idx = 1;
do{
ch = getchar();
ma[i][idx++] = ch;
}while(ch!='\n');
}
int x,y;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(j%2){
x = i*4-1,y = j*6-1;
if(ma[x-1][y+3]==' '){ // 左上
add(toid(i,j),toid(i-1,j+1));
}
if(ma[x+1][y+3]==' '){ // 左
add(toid(i,j),toid(i,j+1));
}
if(ma[x+2][y]==' '){ // 下
add(toid(i,j),toid(i+1,j));
}
}else{
x = i*4+1,y = j*6-1;
if(ma[x-1][y+3]==' '){ // 左
add(toid(i,j),toid(i,j+1));
}
if(ma[x+1][y+3]==' '){ // 左下
add(toid(i,j),toid(i+1,j+1));
}
if(ma[x+2][y]==' '){ // 下
add(toid(i,j),toid(i+1,j));
}
}
if(ma[x][y]=='S'){sp = toid(i,j);}
if(ma[x][y]=='T'){tp = toid(i,j);}
}
}
int ans = dij();
if(ans!=inf) printf("%d\n",ans+1);
else puts("-1");
}
return 0;
}
F
Construction issues
- Ideas: a priority to kill a and b, a and b to figure out the total number of days were killed last (long and greater than ha + hb, there must be a solution to the composition and HB ha), due to the lexicographic order. the minimum, so far as possible when a hit configured
hit a: lower_bound calculating a dead time POS, and sum [pos] -ha to play a number of attack (attack corresponding to a day), if the sum [last] - sum [pos]> = hb explained later can kill b, otherwise use more offensive power play that day b.
hit b:. b can not all be hit direct hit b, to bring harm to play a specific earnings look it Notes
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6+10;
ll sum[N];
int main(){
int n = 1e5+10;
for(int i=1;i<n;++i){
sum[i] = sum[i-1] + i;
}
int t; scanf("%d",&t);
while(t--){
ll ha,hb,ta,tb;
scanf("%lld%lld%lld%lld",&ha,&hb,&ta,&tb);
ll last = lower_bound(sum+1,sum+n,ha+hb)-sum; // a,b都被打死
string sa,sb;
ll pos = lower_bound(sum+1,sum+n,ha) - sum ; // 打死a的回合
ll los = sum[pos] - ha; // 盈余的伤害
ll s1 = pos*ta + last*tb; // 收到的攻击
if(sum[last] - sum[pos] >= hb){ // 后面之间可以把b打死
for(ll i=1;i<=pos;++i) sa += 'A';
}else{ // 打不死 要在前面穿插一次攻击
for(ll i=1;i<=pos;++i){
if(i!=los) sa+='A';
else sa += 'B';
}
}
for(ll i=pos+1;i<=last;++i) sa+='B';
pos = lower_bound(sum+1,sum+n,hb)-sum; // 打死b的回合
ll s2 = last*ta + pos*tb; // 收到的伤害
if(s1<s2){// 先a更优
printf("%lld ",s1);
cout << sa+'\n';
}else{
los = sum[pos] - hb; // 盈余伤害
ll lb1 = upper_bound(sum+1,sum+n,los) - sum - 1;
ll bac = sum[last] - sum[pos]; // 后面能对a造成的伤害
if(bac+sum[lb1]>=ha){// "AAABBBAAA"
for(ll i=1;i<=lb1;++i){
sb += 'A';
}
for(ll i=lb1+1;i<=pos;++i){
sb += 'B';
}
}else{// AB交替 直到后面能打死A
ll left = ha-bac; // 还需要多少能打死A
for(ll i=1;i<=pos;++i){
if(left-i>i || left==i){ // left-i<=i 就说明后面不能构成整数天去打a了,会亏攻击力就不能去打a
left -= i;
sb += 'A';
}else{
sb += 'B';
}
}
}
for(ll i=pos+1;i<=last;++i){
sb += 'A';
}
printf("%lld ",s2);
if(s2<s1) cout << sb +'\n';
else cout << min(sa,sb) +'\n';
}
}
return 0;
}