- B题
我觉得这应该是一道模拟题,就照题目的意思进行模拟就好了。
每一次先找出不是1的数,从这个不是1的数开始寻找一个最小的数,当碰到1的时候退出这个寻找的循环,然后将找出的最小的数都减去在这个范围内的数。累加这个最小的数。一直重复着,一直到找不到不是1 的数的时候退出循环。
代码:
#include<bits/stdc++.h>
#define IO std::ios::sync_with_stdio(0),cin.tie(0)
using namespace std;
typedef long long ll;
const int N=1e6+10;
const int INF=0x7f7f7f7f;
int num[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
int minn=0,a=1;
ll sum=0;
while(1)
{
int b=0;
for(int i=a;i<=n;i++)
{
if(num[i]==1) break;
if(num[i]!=1) num[i]-=minn;
}
for(int i=a;i<=n;i++)
{
if(num[i]!=1)
{
b=i;
break;
}
}
if(b==0) break;
a=b;
minn=INF;
for(int i=a;i<=n;i++)
{
if(num[i]==1) break;
minn=min(minn,num[i]);
}//printf("%d %d %d \n",minn,a,sum);
minn--;
sum+=minn;
}
printf("%lld\n",sum);
}
return 0;
} - c题
是一道签到题,但是我却做了好久,因为我使用double,输出以lf输出,这样写是没有问题的,有问题的是我提交的是第一个,所以一直错误,第一个应该是c99的,我下面的代码要提交的是第二个,才能通过。
代码:
#include<bits/stdc++.h>
#define IO std::ios::sync_with_stdio(0),cin.tie(0)
#define PI 3.14
using namespace std;
typedef long long ll;
const int N= 10000;
const int INF=0x7f7f7f7f;
int mp[N][N],vis[N][N];
int d[][2]={{1,0},{0,1},{-1,0},{0,-1}};
int n,cnt=INF;
int main()
{
cin>>T;
while(T--)
{
double a,b;
scanf("%lf",&a);
b=2.0*PI*(a/2.0)*(a/2.0)+a*a*1.0;
printf("%.2lf\n",b);
}
return 0;
}- E题
这题可以使用二分查找,但是呢,强大的STL中有一个函数就是二分查找的函数,所以就不能这么麻烦的手写二分啦。要记得使用这个函数的时候,查找的数要自加1,为了以防找到一个和自己一样的数,找到的数要进行标记,我这里的是将找出的数全部改为-1,我想的是应该没有哪一个数要比-1小了吧,而且输出的都是正整数,O(∩_∩)O哈哈~,不要忘记每一次查询都要sort一遍哦,(* ^▽^),*(小声逼逼,我看了一下,好像没有那个人和我一样呢,用STL,嘿嘿,可能是我没有仔细看)
代码:
#include<bits/stdc++.h>
#define IO std::ios::sync_with_stdio(0),cin.tie(0)
using namespace std;
typedef long long ll;
const int N= 100000+5;
const int INF=0x7f7f7f7f;
//int mp[N][N],vis[N][N];
int d[][2]={{1,0},{0,1},{-1,0},{0,-1}};
int n,cnt=INF;
ll num[N],vis[N];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld",&num[i]);
sort(num,num+n);
ll cnt=0;
for(int i=0;i<n;i++)
{
ll x;
scanf("%lld",&x);
ll pj=lower_bound(num,num+n,x+1)-num;
if(num[pj]>x)
{
cnt++;
num[pj]=-1;
sort(num,num+n);
}
}
printf("%lld\n",cnt);
}
return 0;
}- F题
这题大家应该都知道的一个定理:三角形两边之和大于第三边,两边之差小于第三边。并且这两个条件缺一不可。既然这样,我们可以找出1,1,2,3,4,5......这样的分段长度,因为两边之和不能大于第三,又要尽可能的取多,所以只好这样取了。因此可以发现,这是斐波那契数列,所以公式也可以很快的得出,限定的条件就是取出的这些分段的和要是原木棒的和,因此要把这些数相加小于或者等于小木棒的长度。
#include<bits/stdc++.h>
#define IO std::ios::sync_with_stdio(0),cin.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=100+1;
ull f[N];
void fun()
{
f[1]=1,f[2]=1;
for(int i=3;i<=101;i++)
f[i]=f[i-1]+f[i-2];
}
int main()
{
IO ;
int t;
cin>>t;
fun();
while(t--)
{
ull n;
cin>>n;
ull i=1,cnt=0;
while(1)
{ //cout<<n<<' '<<f[i]<<endl;
if(n<f[i]) break;
n-=f[i];
cnt++;
i++;
}
cout<<cnt<<endl;
}
return 0;
}- H 题
这也是一道有关数学的题,要是知道这个定理的肯定知道要怎么做了,重要的是要知道高精度怎么写。
平面内有n条直线,其中没有两条互相平行,也没有三条交于一点,一共有n*(n-1)/2个交点
就是这样的定理。(这是我查百度的呢,因为我只知道公式是什么,不知道这怎么表述,哎)这题我是当长度大于10的时候,我才使用了高精度,如果每一个都是使用高精度的话,时间复杂度会很大的。所以在这个地方我进行了判断。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e7+10;
int a[N],b[N],c[N],res[N];
string s;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
cin>>s;
int len=s.length();
if(len<=10)
{
long double a=0,b;
int x=0;
for(int i=len-1;i>=0;i--)
a+=pow(10,x)*(s[i]-'0'),x++;
printf("%.0Lf\n",a*(a-1)/2);
}
else
{
memset(c,0,sizeof c);
memset(res,0,sizeof res);
int ma=0,mb=0;
for(int i=len-1;i>=0;i--)
a[ma++]=s[i]-'0',b[mb++]=s[i]-'0';
int up=-1;//b减去1
for(int i=0;i<mb;i++)
{
b[i]=b[i]+up;
if(b[i]<0)
{
b[i+1]-=1;
b[i]+=10;
}
up=0;
}
if(b[mb-1]==0) mb--;
up=0;//两数相乘
for(int i=0;i<ma;i++)
{
up=0;
for(int j=0;j<mb;j++)
{
c[i+j]+=a[i]*b[j]+up;
up=c[i+j]/10;
c[i+j]%=10;
}
c[mb+i]=up;
}
int lenc=max(ma,mb)*2-1;
while(c[lenc]==0&&lenc>0)
lenc--;
up=0;//除法
for(int i=lenc;i>=0;i--)
{
res[i]=(up*10+c[i])/2;
up=(up*10+c[i])%2;
}
int lenres=lenc;
while(res[lenres]==0&&lenres>0)
lenres--;
for(int i=lenres;i>=0;i--)
printf("%d",res[i]);printf("\n");
}
s.clear();
}
return 0;
}- J 题
这题我是暴力的,没有想到竟然过了。我的字符串的下标的是从0开始的,因此我从1开始寻找一个和s[0]相同的字符,如果出现的话就从这个字符开始找后面有没有与s[1]相同的,如果有就计数,如果没有就退出寻找的循环。回到刚刚找到s[0]的地方继续向后查找一个与s[0]相同的字符,如果有则重复着刚刚的操作。就一直这样的找出一个最长的。
代码:
#include<bits/stdc++.h>
#define IO std::ios::sync_with_stdio(0),cin.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=100+1;
ull f[N];
string s,temp;
int main()
{
IO;
int t;
cin>>t;
while(t--)
{
cin>>s;
temp=s;
int len=s.length(),res=0;
for(int i=1;i<len;i++)
{
if(temp[i]==s[0])
{
int cnt=0;
for(int j=i,k=0;j<len;j++,k++)
{
if(temp[j]!=s[k]) break;
cnt++;
}
res=max(res,cnt);
}
}
cout<<res<<endl;
}
return 0;
}


京公网安备 11010502036488号