前言 超级迟到的博客
SSL NO.1 面积
题目
求a和b的值,使阴影部分面积最大。
分析
首先看到这个三角形
一看就是直角三角形,短直角边为a/2,斜边为r,那么长直角边可以用勾股定理算出来,乘2后得到长方形的长,算出两个长方形再减去中间的部分求a,b最大值,所以枚举a,b 1至2*r-1即可。
#include <cstdio>
#include <cmath>
using namespace std;
int r,a,b; long double maxn;
int main(){
freopen("maxs.in","r",stdin);
freopen("maxs.out","w",stdout);
scanf("%d",&r);
for (int i=1;i<2*r;i++)
for (int j=1;j<2*r;j++){
long double t1=sqrt(r*r*1.0-i*i/4.0);
long double t2=sqrt(r*r*1.0-j*j/4.0);
long double t=t1*i*2.0+t2*j*2.0-i*j*1.0;
if (t>maxn) maxn=t,a=i,b=j;
}
return !printf("%d\n%d",a,b);
}
SSL NO.2 文件名排序
代码(没有太多的技巧)
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
struct sor{char basic[10],extra[5]; short rank,ans;}so[101];
short n,k,l,r; bool ok[101];
bool cmp(sor x,sor y){
if (ok[x.rank]!=ok[y.rank]) return ok[x.rank]>ok[y.rank];
if (strcmp(x.extra,y.extra))
return strcmp(x.extra,y.extra)<0;
else return strcmp(x.basic,y.basic)<0;
}
bool cmp1(sor x,sor y){return x.rank<y.rank;}
void init(int i){
char c=getchar(),first[10]=""; int l1=0,l2=0,poi;
while (!isalnum(c)) c=getchar();
while (isalnum(c)) first[l1++]=c,c=getchar();
if (c==46){
ok[i]=1; poi=++l; c=getchar();
while (isalnum(c)) so[poi].extra[l2++]=c,c=getchar();
} else poi=--r;
so[poi].rank=i; for (int j=0;j<l1;j++) so[poi].basic[j]=first[j];
}
int main(){
freopen("sort.in","r",stdin);
freopen("sort.out","w",stdout);
scanf("%d",&n); r=n+1;
for (int i=1;i<=n;i++) init(i);
stable_sort(so+1,so+1+n,cmp);
for (int i=1;i<=n;i++) so[i].ans=i;
stable_sort(so+1,so+1+n,cmp1);
for (int i=1;i<=n;i++) printf("%d\n",so[i].ans);
return 0;
}
SSL NO.3 取数
代码(记忆化搜索)
#include <cstdio>
#include <cctype>
#define g(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
const short dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
short n,m,a[101][101],f[101][101][4],ans;
short in(){
short ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int max(int a,int b){return (a>b)?a:b;}
int dz(int i,int j,int way){
short x=i+dx[way],y=j+dy[way];
if (x<1||y<1||x>n||y>m) return 32768;
short ans=a[i][j]-a[x][y];
if (ans<0) ans=-ans; return ans;
}
void dfs(int i,int j,int way){
if (f[i][j][way]) return; else f[i][j][way]=1;
short x=i+dx[way],y=j+dy[way];
if (x<1||y<1||x>n||y>m||a[x][y]<=a[i][j]) return;
g(dir,0,3){
dfs(x,y,dir);
if (dz(x,y,dir)!=dz(i,j,way)) continue;
f[i][j][way]=max(f[i][j][way],f[x][y][dir]+1);
}
}
int main(){
freopen("pick.in","r",stdin);
freopen("pick.out","w",stdout);
n=in(); m=in();
g(i,1,n) g(j,1,m) a[i][j]=in();
g(i,1,n) g(j,1,m) g(way,0,3) dfs(i,j,way),ans=max(ans,f[i][j][way]);
return !printf("%d",ans);
}
SSL NO.4 航空公司
代码(kruskal)
#include <cstdio>
#include <cctype>
#include <cmath>
#include <algorithm>
#define g(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
struct node{short x,y; double w;}e[499501];int m;
short n,f[1001],x[1001],y[1001],z[1001],k; double ans;
int in(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)&&c!='-') c=getchar();
if (c=='-') c=getchar(),f=-f;
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
int getf(int u){return (f[u]==u)?u:f[u]=getf(f[u]);}
bool cmp(node x,node y){return x.w<y.w;}
int main(){
freopen("air.in","r",stdin);
freopen("air.out","w",stdout);
n=in();
g(i,1,n)
{
x[i]=in(); y[i]=in(); z[i]=in(); f[i]=i;
g(j,1,i-1){
e[++m].x=i; e[m].y=j;
e[m].w=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))-z[i]-z[j];
}
}
stable_sort(e+1,e+1+m,cmp);
g(i,1,m){
int fa=getf(e[i].x),fb=getf(e[i].y);
if (fa==fb) continue;
k++; if (k==n) break;
f[fa]=fb; ans=e[i].w;
}
return !printf("%.lf",ceil(ans));
}
总结
除了第一题比较高境界外,其它貌似还算比较水,不过第二题strcmp蒙了,主要是懒得打字典序。