A纯水题,B题卡了50分钟,然后就没有然后了……
下来后C题是最长上升子序列,当时先做C可能会好一点,D题卡了今天半下午……吃了一碗叙府燃面脑洞大开,怒AC之……E题太神表示不会。。
A题
一种通讯方式求总字节数,水到没朋友,总数遇+就++,遇-就--,然后无脑*。算是复习string了~
AC代码
#include<iostream>
using namespace std;
int main()
{ string s;
int num=0,sum=0,pos;
while(getline(cin,s))
{
if(s[0]=='+')
num++;
else if(s[0]=='-')
num--;
else
{
for(int i=0; i<s.size(); i++)
{
if(s[i]==':')
{
pos=i;
break;
}
}
sum+=(s.size()-pos-1)*num;
}
}
cout<<sum<<endl;
return 0;
}
B题
排版问题,应该算是比较简单的题,不过注意认真研读样例,先测出最长字符串,然后以最长字符串为基准,减去其余各个字符串,如果为偶数则平分,如果为奇数则先左边少一格然后右边少一格交替前行……
AC代码
<span style="font-size:10px;">#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[1005][1005];
int pos[1005];
int maxn(int x,int y)
{
if(x>y) return x;
return y;
}
int main()
{ int i=0,maxlen=0,is=0;
while(gets(s[i]))
{
maxlen=maxn(maxlen,strlen(s[i]));
i++;
}
for(int j=0;j<maxlen+2;j++)
cout<<'*';
cout<<endl;
int w=0;
for(int j=0;j<i;j++)
{
cout<<'*';
int m=maxlen-strlen(s[j]);
if(m%2==0)
{ int a=m/2;
for(int j=0;j<a;j++)
cout<<" ";
cout<<s[j];
for(int j=0;j<m-a;j++)
cout<<" ";
cout<<'*'<<endl;
}
else
{
if(w==0)
{int a=(m-1)/2;
for(int j=0;j<a;j++)
cout<<" ";
cout<<s[j];
for(int j=0;j<m-a;j++)
cout<<" ";
cout<<'*'<<endl;
w=1;}
else
{int a=(m+1)/2;
for(int j=0;j<a;j++)
cout<<" ";
cout<<s[j];
for(int j=0;j<m-a;j++)
cout<<" ";
cout<<'*'<<endl;
w=0;}
}
}
for(int j=0;j<maxlen+2;j++)
cout<<'*';
return 0;
}</span>
C题
有一堆信封一张卡片,凡是大于卡片的信封升序排列。(w1<=w2,h1<h2||w1<w2,h1<=h2)先W后H的最长上升子序列问题。
AC代码
<span style="font-size:10px;">#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct data
{
int w,h,id;
}g[5010];
int f[5010],p[5010];
int i,j,k,ans,n,w,h;
bool cmp(data a,data b)
{
if(a.w!=b.w)
return a.w<b.w;
return a.h<b.h;
}
void out(int j)
{
if(j<0)return;
out(p[j]);
printf("%d%c",g[j].id,--ans?' ':'\n');
}
int main()
{
while(~scanf("%d%d%d",&n,&w,&h))
{
for(i=0;i<n;i++)
scanf("%d%d",&g[i].w,&g[i].h),g[i].id=i+1;
sort(g,g+n,cmp);
for(i=0;i<n;i++)
if(g[i].w>w&&g[i].h>h)f[i]=1;
else f[i]=-1e7;
for(i=0;i<n;i++)
for(p[i]=-1,j=0;j<i;++j)
if(g[j].w<g[i].w&&g[j].h<g[i].h&&f[j]+1>f[i])
{
f[i]=f[j]+1;
p[i]=j;
}
for(i=j=0;i<n;++i)
if(f[i]>f[j])j=i;
ans=f[j];
if(ans>0)
{
printf("%d\n",ans);
out(j);
}
else puts("0");
}
return 0;
}</span>
D题
贪心。N个包求最大价值问题,这种问题麻烦在讨论情况有点微多。刚开始的想法是先分别降序排序,然后把占空为2的包放满了再塞占空为1的包。看看剩下占空为1的包两个能不能替换掉一个占空为2的包。
刚开始的时候没有考虑到
1总容量特别大可以都放的情况,接着没有考虑到
2占空为2的包放不满但占空为1的包没用上的情况……最后发现拿两个换一个是一个极其逗的想法,这样导致的后果是
3如果占空为1的包剩余奇数而有最后一个包的价值是大于那个占空为2的包的……友情给予测试样例……
1
3 2
1 2
2 7
1 3
2
12 8
2 20
1 9
1 8
1 7
1 9
1 8
1 7
1 6
1 5
1 4
1 3
1 2
2 20
1 9
1 8
1 7
1 9
1 8
1 7
1 6
1 5
1 4
1 3
1 2
3
2 2
1 34
2 1
AC代码
#include<iostream>
#include <algorithm>
#include<cstdio>
using namespace std;
#define MAX 100010
struct vehicles
{
int capacity,pos;
}fir[MAX],sec[MAX];
bool cmp(vehicles a,vehicles b)
{
return a.capacity>b.capacity;
}
int main()
{
int n,v,t,p,i=1,j=1,k=1,ans,ans1,ans2,x1,x2,c[MAX];
cin>>n>>v;
while(n--)
{
cin>>t>>p;
if(t==1)
{
fir[j].capacity=p;fir[j++].pos=i++;
}
else
{
sec[k].capacity=p;sec[k++].pos=i++;
}
}j--;k--;
if(j+2*k<=v)
{
int sum1=0,q1=1;
for(int i=1;i<=j;i++) sum1+=fir[i].capacity,c[q1++]=fir[i].pos;
for(int i=1;i<=k;i++) sum1+=sec[i].capacity,c[q1++]=sec[i].pos;
cout<<sum1<<endl;
for(int i=1; i<=j+k; i++)
printf("%d%c", c[i], i == j+k? '\n' : ' ');
return 0;
}
sort(fir+1,fir+j+1,cmp);
sort(sec+1,sec+k+1,cmp);
// cout<<j<<" "<<k<<endl;
// for(int i=1;i<=j;i++)cout<<fir[i].pos<<" ";
// cout<<endl;
// for(int i=1;i<=k;i++) cout<<sec[i].pos<<endl;
ans2=min(v/2,k);ans1=v-ans2*2;
//cout<<ans1<<" "<<ans2<<endl;
// cout<<2+ans1<<" "<<ans2<<" "<<j<<" "<<fir[2+ans1].capacity+fir[1+ans1].capacity<<" "<<sec[ans2].capacity<<endl;
for(x1=2+ans1,x2=ans2;x1<=j+1&&x2>0;x1=x1+2,x2--)
{if(fir[x1].capacity+fir[x1-1].capacity>sec[x2].capacity)
{
ans1+=2;ans2--;
}
else break;}
if(ans1==j+1) ans1--;
//cout<<ans1<<" "<<ans2<<endl;
int sum=0,q=1;
for(int i=1;i<=ans1;i++) sum+=fir[i].capacity,c[q++]=fir[i].pos;
for(int i=1;i<=ans2;i++) sum+=sec[i].capacity,c[q++]=sec[i].pos;
//if(v==0)
//{cout<<'0'<<endl;return 0;}
cout<<sum<<endl;
for(int i=1; i<=ans1+ans2; i++)
printf("%d%c", c[i], i == ans1+ans2? '\n' : ' ');
return 0;
}
E题
太神,钻研中……
AC代码
<pre name="code" class="cpp"><span style="font-size:10px;">#include<iostream>
#include<cmath>
#include<cstdio>
#define eps 1e-7
using namespace std;
int dir[4][2]= { {1,0},{-1,0},{0,1},{0,-1} };
double x=0,y=0;
struct node
{
double x,y,r;
} c[3];
double p2(double x)
{
return x*x;
}
double dis(double x, double y, double xx, double yy)
{
return sqrt(p2(x-xx)+p2(y-yy));
}
double f(double x, double y)
{
double tmp[3],ans=0;
for(int i=0; i<3; i++)
tmp[i]=dis(x,y,c[i].x,c[i].y)/c[i].r;
for(int i=0; i<3; i++)
ans+=p2(tmp[i]-tmp[(i+1)%3]);
return ans;
}
void init()
{
for(int i=0; i<3; i++)
{
scanf("%lf%lf%lf", &c[i].x,&c[i].y,&c[i].r);
x+=c[i].x/3;
y+=c[i].y/3;
}
}
int main(int argc, char const *argv[])
{
init();
double step=1;
while(step>eps)
{
double tmp=f(x,y);
int tag=-1;
for(int i=0; i<4; i++)
{
double cnt=f(x+dir[i][0]*step, y+dir[i][1]*step);
if(cnt<tmp)
{
tmp=cnt;
tag=i;
}
}
if(tag==-1)
{
step/=2;
}
else
{
x=x+dir[tag][0]*step;
y=y+dir[tag][1]*step;
}
}
if(f(x,y)<eps)
printf("%.5lf %.5lf\n", x,y);
return 0;
}</span>