A题好福利,哇哈哈
#include<cstdio>
#include<memory>
using namespace std;
int data[1000010];
double dmax(double a,double b){
return a>b?a:b;
}
int abs(int a){
return a>0?a:-a;
}
int main(){
int t,tn,n,i,j;
double max;
scanf("%d",&t);
for(tn=1;tn<=t;tn++){
scanf("%d",&n);
memset(data,-1,sizeof(data));
for(i=1;i<=n;i++){
scanf("%d",&j);
scanf("%d",&data[j]);
}
j=-1;
max=-1.0;
for(i=0;i<=1000010;i++) if(data[i]!=-1){
if(j!=-1) max=dmax(max,(double)abs(data[i]-data[j])/(double)(i-j));
j=i;
}
printf("Case #%d: %.2lf\n",tn,max);
}
return 0;
}
B题 我试着从右上沿对角线填,每填完一种颜色换下一种颜色,填完一半并填完当前颜色以后,剩下的就可以随便填了,5x5以内能AC,数据再大我也没把握,但我觉得这种填法挺有意思的
15ms Accept!!
--------------------------------------
#include<cstdio>
#include<algorithm>
using namespace std;
typedef struct{
int index;
int number;
int used;
}color;
bool cmp(color a,color b){
return a.number>b.number;
}
color c[26];
int map[6][6],n,m,k,hmax;int nextcolor(int l){
int i,mmax=0,ncl=0;
for(i=1;i<=k;i++) if(!c[i].used&&c[i].number<=l&&mmax<c[i].number){
mmax=c[i].number;
ncl=i;
}
if(ncl==0) for(i=k;i>=1;i--) if(!c[i].used) {ncl=i;break;}
c[ncl].used=1;
return ncl;
}
void printmap(){
int sum,i,j,d,p;
if(n*m%2==0) j=m-1;
else j=m;
d=j>0?0:1;
p=1;
c[1].used=1;
sum=c[1].number;
for(i=1;i<=hmax;i++){
map[1+d][j+d]=c[p].index;
if(--c[p].number==0){
p=nextcolor(hmax-sum);
sum+=c[p].number;}
d++;
if(j+d>m||1+d>n){
j-=2;
d=0;
while(j+d<1) d++;
}
}
if(n*m%2==0) j=m;
else j=m-1;
d=j>0?0:1;
if(sum!=hmax){
while(c[p].number){
map[1+d][j+d]=c[p].index;
if(--c[p].number==0) break;
d++;
if(j+d>m||1+d>n){
j-=2;
d=0;
while(j+d<1) d++;
}
}
p=nextcolor(0);
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(!map[i][j]){
map[i][j]=c[p].index;
if(--c[p].number==0) p=nextcolor(0);
}for(i=1;i<=n;i++){
printf("%d",map[i][1]);
for(j=2;j<=m;j++) printf(" %d",map[i][j]);
printf("\n");
}
}
int main(){
int t,tn,i;
scanf("%d",&t);
for(tn=1;tn<=t;tn++){
scanf("%d %d %d",&n,&m,&k);
for(i=1;i<=k;i++){
c[i].index=i;
c[i].used=0;
scanf("%d",&c[i].number);
}
sort(c+1,c+1+k,cmp);
hmax=(int)((double)n*m/2.0+0.5);
printf("Case #%d:\n",tn);
if(c[1].number>hmax) printf("NO\n");
else{
memset(map,0,sizeof(map));
printf("YES\n");
printmap();
}
}
return 0;
}
C题 最小公倍数的题,做完D再回来做
--------------------------------------------
问题并不复杂,常见的运动分解,在x,y轴两个分解运动的公共周期内如果不会碰撞就永远不会碰撞
数据非常大,需要用到64位int,否则计算lcm(2x,2y)会溢出,判断在公共周期内两坐标轴是否会同时碰撞时我采用了二分搜索,187msAC
从开始写到AC花了快1个小时的时间。。。昨天的思考时间无法计算。。。我果然太小看ACM了啊。。。乖乖刷水题去好了
#include<cstdio>
double tx[1000001],ty[1000001];
int gcd(int a,int b){
if(a%b==0) return b;
else return gcd(b,a%b);
}
int abs(int a){
return a>0?a:-a;
}
int max(int a,int b){
return a>b?a:b;
}
double hilove(int p1,int p2,__int64 l){
if(p1==p2) return 0;
return abs(p1-p2)/2.0+l-max(p1,p2);
}
double locate(int s,__int64 l,double t){
while(t>2*l) t-=2*l;
if(t<=l-s) return s+t;
if(t>l-s&&t<=2*l-s) return 2*l-t-s;
if(t>2*l-s) return t-2*l+s;
}
int binary_search(int l,int r,double t){
int mid=(r+l)/2;
if(tx[mid]==t) return mid;
if(mid==l) return 0;
if(tx[mid]>t) binary_search(l,mid,t);
else binary_search(mid,r,t);}
int main(){
__int64 xyl,xl,yl;
int t,tn,x1,x2,y1,y2,txl,tyl,i,pos;
scanf("%d",&t);
for(tn=1;tn<=t;tn++){
scanf("%I64d %I64d\n%d %d %d %d",&xl,&yl,&x1,&y1,&x2,&y2);
xyl=xl/gcd(xl,yl)*yl*2;
tx[1]=hilove(x1,x2,xl);
ty[1]=hilove(y1,y2,yl);
printf("Case #%d:\n",tn);
if(tx[1]==0&&ty[1]==0){
printf("%.1lf %.1lf\n",(double)x1,(double)y1);
continue;
}
if(tx[1]==0){
printf("%.1lf %.1lf\n",locate(x1,xl,ty[1]),locate(y1,yl,ty[1]));
continue;
}
if(ty[1]==0){
printf("%.1lf %.1lf\n",locate(x1,xl,tx[1]),locate(y1,yl,tx[1]));
continue;
}
for(txl=1;tx[txl]<=xyl;txl++) tx[txl+1]=tx[txl]+xl;
for(tyl=1;ty[tyl]<=xyl;tyl++) ty[tyl+1]=ty[tyl]+yl;
for(i=1;i<tyl;i++) if(pos=binary_search(1,txl,ty[i])) break;
if(!pos) printf("Collision will not happen.\n");
else printf("%.1lf %.1lf\n",locate(x1,xl,ty[i]),locate(y1,yl,ty[i]));
}
}
D题 折腾了挺久的,今天精神不好,睡了3个小时没到,晚上回去一定好好补觉啊魂淡,头等大事就是睡觉啊魂淡!!!有什么事情有这个重要啊魂淡魂淡魂淡!!
#include<cstdio>
#include<memory>
using namespace std;
int dp[202][202];
int vis[202][202];
int eh[202];
int min(int a,int b){
return a<b?a:b;
}
int main(){
int t_t,t_tt,n,ah,sum,i,k,d;
scanf("%d",&t_tt);
for(t_t=1;t_t<=t_tt;t_t++){
scanf("%d",&n);
sum=0;
for(i=1;i<=n;i++){scanf("%d",&ah);sum+=ah;}
for(i=1;i<=n;i++) scanf("%d",eh+i);
eh[0]=eh[n+1]=0;
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++) dp[i][i]=eh[i-1]+eh[i+1];
for(k=1;k<n;k++)
for(i=1;i+k<=n;i++)
for(d=i;d<=i+k;d++){
if(vis[i][i+k]) dp[i][i+k]=min(dp[i][i+k],dp[i][d-1]+dp[d+1][i+k]+eh[i-1]+eh[i+k+1]);
else {vis[i][i+k]=1;dp[i][i+k]=dp[i][d-1]+dp[d+1][i+k]+eh[i-1]+eh[i+k+1];}
}
printf("Case #%d: %d\n",t_t,sum+dp[1][n]);
}
}
E题 呐呐呐,我又回来了!
-------------------------
去刷水题了。。。。。。。。
------------------------
啦啦啦,我又萌萌哒回来啦,先说下思路,用一个矩阵保存输入的点,每当选定一个L的时候将L涉及的点从矩阵中删去,统计剩余矩阵中的所有L
这样想法是没错的。。。但是超时是肯定哒啦~~
--------------------------
哪位大腿有不TLE的码吗?给人家看看好不好。。。
K题 签个到,我逛4399去了,\(^o^)/~
#include<cstdio>
int s[3000010];
int main(){
int tn,tnn,n,i,min,sum;
scanf("%d",&tnn);
for(tn=1;tn<=tnn;tn++){
scanf("%d",&n);
min=10000000;
sum=0;
for(i=1;i<=n;i++) scanf("%d",&s[i]);
for(i=n;i>=1;i--){
if(s[i]>min) sum++;
else min=s[i];
}
printf("Case #%d: %d\n",tn,sum);
}
return 0;
}