导弹袭击,炼金术士的疑惑,老司机的狂欢

T1

noip18_测试总结
来自cf原题
考场直接暴力枚举 \(A,B\),15pts。

正解:

首先时间的表达式,\(T=\frac{A}{a_{i}}+\frac{B}{b_{i}}\),然后以\(\frac{1}{a_{i}}\) 为x轴,\(\frac{1}{b_{i}}\) 为y轴,建立坐标系。
将原式子转换一下,即有

\[y=-\frac{A}{B}x+\frac{T}{B} \]

式子斜率为负,维护左下凸包,单调栈求解。

没调出来,所以贴std

sbstd
#include<bits/stdc++.h>
#define LL long long
#define LD double
#define RG register
#define R RG int
#define G if(++ip==ie)fread(ip=buf,1,N,stdin)
using namespace std;
const int N=3e5+9;
int q[N],ne[N];
LD k[N];bool f[N];
char buf[N],*ie=buf+N,*ip=ie-1;
struct Point{
	int x,y,id;
	inline bool operator<(RG Point a)const{
		return x>a.x||(x==a.x&&y>a.y);
	}
}p[N];
inline int in()
{
	G;while(*ip<'-')G;
	R x=*ip&15;G;
	while(*ip>'-'){x*=10;x+=*ip&15;G;}
	return x;
}
inline LD Slope(RG Point&i,RG Point&j)
{ return(LD)i.x*j.x*(j.y-i.y)/((LD)i.y*j.y*(j.x-i.x)); }
int main()
{
	R n=in(),t,ry=0,rx;
	for(R i=1;i<=n;++i)
	{
		p[i].x=in();p[i].y=in();p[i].id=i;
		if(ry<p[i].y||(ry==p[i].y&&rx<p[i].x))ry=p[i].y,rx=p[i].x;
	}
	sort(p+1,p+n+1);q[t=1]=1;
	for(R i=2;i<=n&&rx<=p[i].x;++i)
	{
		if(p[q[t]].x==p[i].x)
		{
			if(p[q[t]].y==p[i].y)
				ne[p[i].id]=ne[p[q[t]].id],ne[p[q[t]].id]=p[i].id;
			continue;
		}
		while(t>1&&k[t]<Slope(p[q[t]],p[i]))--t;
		q[++t]=i;k[t]=Slope(p[q[t-1]],p[i]);
	}
	for(;t;--t)
		for(R i=p[q[t]].id;i;i=ne[i])
		{ f[i]=1; }
	for(R i=1;i<=n;++i)
		if(f[i])printf("%d ",i);
	return 0;
}

T2

一眼移项,高斯消元求解,然而高斯消元忘了,所以去打只有一个方程式的点,20pts,结果有个sb方程式 \(\Delta H=0\) ,我输出-0.0,考后我直接????,八哥暴怒

正解:

就是移项,高斯消元,把要求焓的方程式的系数都消成0,此时该方程式=右边的值的负数即为答案,注意,求解的方程只消元,不去跟别的方程交换。

恶心的地方就是读入,用俩map统计一下是否出现和物质的编号就好

Code
#include<map>
#include<cstdio>
#include<cstring>
#define MAX 210
#define re register
namespace OMA
{
   int n,cnt;
   double ans,h[MAX];
   double ar[MAX][MAX];
   const int base = 131;
   std::map<int,int>id;
   std::map<int,bool>vis;
   inline void swap(double &a,double &b)
   { double t=a; a=b; b=t; }
   inline double abs(double a)
   { return a>=0?a:-a; }
   inline int get_hash(char ch[])
   {
     int ash = 0;
     int len = strlen(ch+1);
     for(re int i=1; i<=len; i++)
     { ash = ash*base+ch[i]; }
     return ash;
   }
   inline void Gauss()
   {
     for(re int i=1; i<=n+1; i++)
     {
       int k = i;
       for(re int j=i+1; j<=n; j++)
       {
         if(abs(ar[j][i])>abs(ar[k][i]))
         { k = j; }
       }
       for(re int j=1; j<=cnt+1; j++)
       { swap(ar[i][j],ar[k][j]); }
       for(re int j=1; j<=n+1; j++)
       {
         if(i!=j)
         {
           double temp = ar[j][i]/ar[i][i];
           for(k=i+1; k<=cnt+1; k++)
           { ar[j][k] -= temp*ar[i][k]; }
         }
       }
     }
   }
   signed main()
   {
     char ch[10];
     double tmp;
     scanf("%d",&n);
     for(re int i=1; i<=n; i++)
     {
       while(1)
       {
         scanf("%lf",&tmp);
         scanf("%s",ch+1);
         int temp = get_hash(ch);
         if(!vis[temp])
         { vis[temp] = true,id[temp] = ++cnt; }
         ar[i][id[temp]] = tmp;
         scanf("%s",ch+1);
         if(ch[1]=='=')
         { break ; }
       }
       while(1)
       {
         scanf("%lf",&tmp);
         scanf("%s",ch+1);
         int temp = get_hash(ch);
         if(!vis[temp])
         { vis[temp] = true,id[temp] = ++cnt; }
         ar[i][id[temp]] = -tmp;
         scanf("%s",ch+1);
         if(ch[1]=='H')
         { break ; }
       }
       scanf("%lf",&h[i]);
     }
     while(1)
     {
       scanf("%lf",&tmp);
       scanf("%s",ch+1);
       ar[n+1][id[get_hash(ch)]] = tmp;
       scanf("%s",ch+1);
       if(ch[1]=='=')
       { break ; }
     }
     while(1)
     {
       scanf("%lf",&tmp);
       scanf("%s",ch+1);
       ar[n+1][id[get_hash(ch)]] = -tmp;
       scanf("%s",ch+1);
       if(ch[1]=='H'&&ch[2]=='=')
       { scanf("%s",ch+1); break ; }
     }
     for(re int i=1; i<=n; i++)
     { ar[i][cnt+1] = h[i]; }
     Gauss();
     printf("%0.1lf\n",ar[n+1][cnt+1]==0?0:-ar[n+1][cnt+1]);
     return 0;
   }
}
signed main()
{ return OMA::main(); }

T3

没改出来,所以先咕了。