A.题斐波那契?
解题思路?
水题,打表解决,递归最后一组测试样例会超时。还有大家读题的时候看一下数据范围啊,忽略了不就没分了?
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
cin>>n;
int f[40];
f[0]=0;
f[1]=1;
for(int i=2;i<40;i++) //打表,先把数据范围内的所有数据算出来。
{
f[i] = f[i-1]+f[i-2];
}
cout<<f[n-1]<<endl;
return 0;
}
B.哥德巴赫?
解题思路?
这个和杭电acm中的分拆素数和类似,主要是别超时。
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int p[1000005];
int prime(int n)//求n是否为素数,除1外,不能被1和自己本身之外的数整除的数就是素数
{
if(n==2)return true;
for(int i=2;i<=sqrt(n);i++)//遍历到n的平方就够了,这样算能快一点。
{
if(n%i==0)return false;
}
return true;
}
int main()
{
int n;
p[0]=p[1]=0;
cin>>n;
//cout<<"n="<<n<<endl;
for(int i=2;i<=n;i++)//打表,将2到n的所有素数都算出来
{
if(prime(i))
{
p[i]=1;
//cout<<i<<" ";
}else{
p[i]=0;
}
}//cout<<endl;
for(int i=2;i<=n/2;i++)
{
if(p[i]==1&&p[n-i]==1)//遍历,如果这个数是素数,那就看看n-这个数是不是也是。
{
cout<<i<<" "<<n-i<<endl;
break;
}
}
return 0;
}
C.碾压
解题思路?
这个题暴力只能得20分,抄了个代码大家看看呀。我是没看懂为啥这样做。
#include<iostream>
using namespace std;
int main()
{
int k,n;
cin>>k>>n;
int a[250],fis[25][25]={0};
for(int x=1;x<=k;++x)
{
for(int r=1;r<=n;r++)
{
cin>>a[r];
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
fis[a[i]][a[j]]++;
}
}
}
int count=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
// cout<<fis[i][j]<<" ";
if(fis[i][j]==k)
count++;
}//cout<<endl;
}
cout<<count<<endl;
return 0;
}
D. 唯一
解题思路?
?说大实话,这个题目描述写得真的是,应该是满足S任意存在一个长为K的字串T。。。。
其实题目真正含义是求最小的字串长度k,就是比如说上面这个例子。
7
ABCDABC //S这个字符串长这样,我们从k=1开始遍历,k指的是截取字串的长度
*&&&&&&&&&&&&&&&*//k=1时,从头开始截取,最后截取的字串序列是:'A','B','C','D','A','B','C'
//然后对这个序列排序,可以看到,截取的字串有重复的,所以最小k不能取1
A
A
B
B
C
C
D
*****
*&&&&&&&&&&&&&&&*//k=2,也有重复的。。。。
AB
AB
BC //字串序列:'AB','BC','CD','DA','AB','BC',大家看懂了吧,后面不写啦。
BC
CD
DA
*****
*&&&&&&&&&&&&&&&*//k=3
ABC
ABC
BCD
CDA
DAB
*****
*&&&&&&&&&&&&&&&*//k=4,好的,我们看这个排序后的序列,终于没有重复的了,最小的K就是它了。
ABCD
BCDA
CDAB
DABC
*****
4
n = int(input())
s = input()
k = 1
list_s = []
count_list = 0
for i in range(1,n): #从k=1开始遍历
#print("k=",i)
count=0
for j in range(n-i+1):
list_s.append("".join(s[j:j+i])) #截取长度为k的字符串,并把截取的字符串添加到list_s中
#print(list_s)
len_list = len(list_s)
for r in range(len_list):
count_list = list_s.count(list_s[r]) #看看有没有重复的字符串
#print(count_list)
if(count_list == 1):
count += 1 #遍历,该字符串没有重复count就加一
if(count == len_list): #要是都没有重复,输出当前k的长度
print(i)
break
#print(list_s)
list_s = [] #list_s这个序列存的是当前长度为k的字串序列,
#k改变了,里面存的字串也得改变
E.果汁生产?
?
?解题思路
?水题,注意边界值,比如说桶的容积和果汁量相等的情况。嘤嘤嘤,我的分。。。。
//桶都满的情况,测试样例
10 10
1 1
2 2
#include<iostream>
using namespace std;
int sum[3];
struct J{
int c;//容积
int m;//果汁量
}j[3];
void dao(int i)
{
sum[i] = j[i].m+j[(i+1)%3].m;//循环的倒果汁,(i+1)%3,这样就可以循环啦
if(sum[i] <= j[(i+1)%3].c)//如果,能倒完整
{
j[(i+1)%3].m = sum[i];
j[i].m = 0;
}
else{//如果第二个桶装不下了,剩下的果汁倒回原来的桶里
j[(i+1)%3].m = j[(i+1)%3].c;
j[i].m = sum[i] - j[(i+1)%3].c;
}
}
int main()
{
for(int i=0;i<3;i++)
{
cin>>j[i].c>>j[i].m;
}
for(int k=1;k<=99;k++)
{
for(int i=0;i<3;i++)//三个桶,循环倒三次
{
dao(i);
//cout<<j[0].m<<" "<<j[1].m<<" "<<j[2].m<<endl;
}
}
dao(0);//循环100次,正好最后剩第一个桶往第二个桶倒(1->2)
cout<<j[0].m<<endl;
cout<<j[1].m<<endl;
cout<<j[2].m<<endl;
return 0;
}
F.平衡
?解题思路
?看了题解,可以用二维前缀和解决。不过这个只能过3个测试样例,剩下的就超时了,让我再想想。
#include<iostream>
using namespace std;
int cnt[1005][1005];
int sum[1005][1005];
int main()
{
int n,x,y,max_x=0,max_y=0,min_x=0,min_y=0;
cin>>n;
cin>>min_x>>min_y;
max_x=min_x;max_y=min_y;
cnt[min_x][min_y]=1;
for(int i=1;i<n;i++)
{
cin>>x>>y;
cnt[x][y]=1;
if(x>max_x)
max_x = x;
if(y>max_y)
max_y = y;
if(min_x>x)
min_x=x;
if(min_y>y)
min_y=y;
}
for(int i=0;i<=max_x+1;i++)
{
for(int j=0;j<=max_y+1;j++)
{
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+cnt[i][j];
//cout<<sum[i][j]<<" ";
}//cout<<endl;
}
int point[4]={0};
int a,b,c,d;
int min_p=n;
for(int i=min_x-1;i<=max_x+1;i++)
{
for(int j=min_y-1;j<=max_y+1;j++)
{
//(c,d)-(a,b)
//(0,0)-(a,b)
a = i;b = j;
c = d = 0;
point[0] = sum[a][b]-sum[a][d-1]-sum[c-1][b]+sum[c-1][d-1];
//(a,0)-(max_x,b)
c=i;d=0;a=max_x;b=j;
point[1] = sum[a][b]-sum[a][d-1]-sum[c-1][b]+sum[c-1][d-1];
//(0,b)-(a,max_y)
c=0;d=j;a=i;b=max_y;
point[2] = sum[a][b]-sum[a][d-1]-sum[c-1][b]+sum[c-1][d-1];
//(a,b)-(max_x,max_y)
c=i;b=j;a=max_x;b=max_y;
point[3] = sum[a][b]-sum[a][d-1]-sum[c-1][b]+sum[c-1][d-1];
int max=0;
for(int k=0;k<4;k++)
{
if(max<point[k])
max=point[k];
}
if(min_p>max)
min_p=max;
}
}
cout<<min_p<<endl;
return 0;
}
官方题解
有的题有好几种解决方法,对于算法优化的时间复杂度比我将的方法要好,大家可以看看。
写在最后?
? 大佬的炮灰就是我。。。。不过还是学到很多东西。。。。其他天的题等我慢慢更新。
还有是不是大佬讲题都默认我们的水平跟他一样啊,真不好意思到处宣扬自己菜。
|