P3680 凸輪廓線

Sxy_Limit發表於2018-12-07

看到這題時,我居然無知的認為這是一道水題,全然不顧那紫色

在提交了40遍後,我明白了…
這(tmd)可(hao)真(nan)水…

如果不會三角函式出門右轉DFS_BFS_DP的題解

uses math;
var i,j,k:longint;
      ans:extended;
      m,n:longint;
      s:ansistring;
      l,r:longint;
      p,t:extended;
      sum:extended;
function half(ch:char):extended;
begin
  if ch='S' then exit(2);
  if ch='C' then exit(pi/2);
  if ch='T' then exit(1.5);
end;
function delta(a,b:extended):extended;
var cosA,cosB,cosC,angle,c:extended;
begin
  c:=sqrt(a*a+b*b);
  cosA:=(b*b+c*c-a*a)/(2*b*c);
  angle:=arccos(cosA)/pi*180;
  exit(angle);
end;function delta2(a,b:extended):extended;
var cosA,cosB,cosC,angle,c:extended;
begin
  c:=sqrt(b*b-a*a);
  cosA:=(b*b+c*c-a*a)/(2*b*c);
  angle:=arccos(cosA)/pi*180;
  exit(angle);
end;
begin
  readln(n);
  readln(s);
  n:=length(s);
  ans:=n*2-2;
  //找第一個不是三角形
  l:=1;
  while (s[l]='T') and (l<n) do inc(l);
  r:=n;
  while (s[r]='T') and (r>1) do dec(r);
  if (l>r) then//全是三角形
  begin
    ans:=n*2+1;
    write(ans:0:9);
    exit;
  end;
  //一個從前往後,一個從後往前,只講一個。
  if l=1 then
  ans:=ans+half(s[1])
  else
  begin
    if s[l]='C' then //三角函式還是很重要的
    begin
    sum:=delta(sqrt(3)*0.5-0.5,l-1)+delta2(sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+(l-1)*(l-1)-0.25),
         sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+(l-1)*(l-1)));//利用三角函式求角度
    ans:=ans+1+{切線的特點}sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+(l-1)*(l-1)-0.25)-(l-1-0.5)+{弧長:}(90-sum)/360*pi;{注意三角函式用的是弧度}
    end
    else
    //正方形簡單多了,勾股定理套一下就好了QAQ
    ans:=ans+1+sqrt((1-0.5*sqrt(3))*(1-0.5*sqrt(3))+(l-1-0.5)*(l-1-0.5))-(l-2);
  end;
  
  if r=n then
  ans:=ans+half(s[n])
  else
  begin
    if s[r]='C' then 
    begin
    sum:=delta(sqrt(3)*0.5-0.5,n-r)+delta2(sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+(n-r)*(n-r)-0.25),
         sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+(n-r)*(n-r)));
    ans:=ans+1+sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+(n-r)*(n-r)-0.25)-(n-r-0.5)+(90-sum)/360*pi;
    end
    else
    ans:=ans+1+sqrt((1-0.5*sqrt(3))*(1-0.5*sqrt(3))+(n-r-0.5)*(n-r-0.5))-(n-r-1);
  end;
  write(ans:0:9);
end.//誒,AC了。

在第43次提交時AC…

因為我評了黑題,它黑了

附上C++,畢竟我轉C了QAQ

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<algorithm>
#define For(i,f,l) for(int pd=(f<l)*1+(l<=f)*-1,i=f;i!=l+pd;i+=pd)
#define repeat for(;;){
#define until(x) if(x){break;}}
#define pi 3.1415926535
using namespace std;
int i,j,k,l,r,n;
double ans,sum,Long;
char s[100];
double Helf(char ch)
{
  if(ch=='S')return 2.0;
  if(ch=='C')return pi/2;
  if(ch=='T')return 1.5;
}
double Delta(double a,double b)
{
  double CosA,Angle,c;
  c=sqrt(a*a+b*b);
  CosA=b/c;
  Angle=acos(CosA)/pi*180;
  return Angle;
}
double Delta_2(double a,double b)
{
  double CosA,Angle,c;
  c=sqrt(b*b-a*a);
  CosA=(2*b*b-2*a*a)/(2*b*c);
  Angle=acos(CosA)/pi*180;
  return Angle;
}
int main()
{
  cin>>n;
  for(i=1;i<=n;i++)cin>>s[i];
  ans=n*2-2;
  l=1;r=n;
  while(s[l]=='T'&&l<n)l++;
  while(s[r]=='T'&&r>1)r--;
  if(l>r)
  {
  	ans=n*2+1;
    cout<<fixed<<setprecision(9)<<ans;
  	return 0;
  }
  if(l==1)
  ans+=Helf(s[1]);
  else
  {
  	Long=l-1;
  	if(s[l]=='C')
  	{
      sum=Delta(sqrt(3)*0.5-0.5,Long)+Delta_2(
      sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+Long*Long-0.25),
      sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+Long*Long));
      ans+=1+sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+Long*Long-0.25)-(Long-0.5)+(90-sum)/360*pi;
    }
    else
    ans+=+1+sqrt((1-0.5*sqrt(3))*(1-0.5*sqrt(3))+(Long-0.5)*(Long-0.5))-(Long-1);
  }
  if(r==n)
  ans+=Helf(s[n]);
  else
  {
  	Long=n-r;
  	if(s[r]=='C')
  	{
      sum=Delta(sqrt(3)*0.5-0.5,Long)+Delta_2(
      sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+Long*Long-0.25),
      sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+Long*Long));
      ans+=1+sqrt((sqrt(3)*0.5-0.5)*(sqrt(3)*0.5-0.5)+Long*Long-0.25)-(Long-0.5)+(90-sum)/360*pi;
    }
    else
    ans+=+1+sqrt((1-0.5*sqrt(3))*(1-0.5*sqrt(3))+(Long-0.5)*(Long-0.5))-(Long-1);
  }
  cout<<fixed<<setprecision(9)<<ans;
}

相關文章