A-HDU-#2087 剪花布条--https://vjudge.net/contest/232807#problem/A
题目大意:给出一个字符串,以及模板串,求字符串中有多少个模板串即子串?
解法:本题因为数据样例比较小所以可以直接使用两个for嵌套暴力匹配,每一次匹配成功便cnt++,进行下一段匹配.
但如果数据范围较大用暴力就会超时,则需要使用KMP算法,我看到题目也没多想直接模板KMP (T_T)。
暴力解法代码如下(百度找的):
#include
#include
int main()
{
char a[1001],b[1001];
int lena,lenb,i,j,sum;;
while(scanf("%s",a)!=EOF&&a[0]!='#')
{
scanf("%s",b);
sum=0;
lena=strlen(a);
lenb=strlen(b);
for(i=0;i
我的kmp代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
C-hdu-2090-算菜价-https://vjudge.net/contest/232807#problem/C
本题比较简单,就是将输入的每种菜价乘购买个数,对于中文菜名直接用字符串储存,不用对其进行处理,注意四舍五入。
#include
#include
#include
using namespace std;
int main()
{
string str;
double i,j,sum = 0;
while(cin >> str >> i >> j)
{
sum = sum + i * j ;
}
cout << fixed << setprecision(1) << sum << endl;
return 0;
}
G-HDU 2094 产生冠军-https://vjudge.net/contest/232807#problem/G
思路:这个可以用set容器来做,每输入一场比赛都将名两个字inset入总的容器中,讲失败的人insert入失败的容器中,如果能分出胜负,那总的容器的长度=失败的容器+1;因为胜者是不会进入失败的容器的!!!这样就不用模拟整个过程那么复杂了!!
#include
#include
#include
#include
#include
using namespace std;
int n,m;
setzon; //总参赛人
setshu; //比赛输过的人
int main()
{
int n;
while(cin>>n&&n){
zon.clear();
shu.clear();
string a,b;
int k=1,u,v;
for(int i=1;i<=n;i++){
cin>>a>>b;
zon.insert(a);
zon.insert(b); //将赢和输的人都加入容器,若容器里面已经存在这个人,则不加入,否则加入
shu.insert(b); //将输的人都加入容器,若容器里面已经存在这个人,则不加入,否则加入
}
if(zon.size()-1==shu.size())
cout<<"Yes"<
J-HDU 2098分拆素数和-https://vjudge.net/contest/232807#problem/J
题解:这题先打一个素数表,然后进行枚举符合计数器++就可以,水题。
#include
#include
using namespace std;
int su[10100]={1,1};
int main()
{
int i,j;
for(i=2;i<10000;i++)
{
if(su[i]==1)
continue;
for(j=i*2;j<10000;j+=i)
su[j]=1;
}
long long int n;
int cnt;
while(cin>>n&&n)
{
cnt=0;
for(i=2;i
K-hdu 2099 - 整除的尾数 -https://vjudge.net/contest/232807#problem/K
题解:这题好像是书上例题,直接暴力求解,比较简单,注意输出格式为%02d。
#include
#include
#include
using namespace std;
int main()
{
int a,b,c[105];
while(cin>>a>>b)
{
int j;
if(a==0&&b==0)break;
for(int i=0;i<102;i++)c[i]=-1;
for(int i=0;i<100;i++)
if((a*100+i)%b==0)
{
c[i]=i;
j=i;
}
for(int i=0;i<100;i++)
{
if(c[i]!=-1)
{ printf("%02d",c[i]);
if(i!=j)
cout<<" ";
}
}
cout<
L-洛谷1223排队接水-https://vjudge.net/contest/232807#problem/L
题解:先排序,然后计算总等待时间,最后输出顺序和平均等待时间。
#include
#include
#include
#include
#include
#include
解题思路:这道题在这套题里面我感觉是相对较难的一道题,是一道最小生成树的模板题,用Kruskal算法来写。将每条路的信息存储起来,并将边的权值按从小到大进行排序,每次选择权值最小的边加入树中,并把边的两个顶点加入到一个集合中,若这两个顶点本身就在一个集合中(即加入这条边就构成了回路),就舍弃这条边判断下一个。直到选取了n-1条边加入树中,最小生成树构造完成。具体看代码。
#include
#include
#include
#include
#define INF 0x3f3f3f3f //定义极大值INF
using namespace std;
int n, m, sum, ans;
int f[1010]; //数组f判断点的集合状态
struct node
{
int x;
int y; //存储边的两个顶点以及权值
int z;
} Q[50010];
bool cmp( node a, node b )
{
return a.z < b.z; //将权值从小到大排列
}
int getf( int v )
{
if( v != f[v] )
f[v] = getf(f[v]); //查找父节点
return f[v];
}
int lian( int t1, int t2 )
{
int v1 = getf(t1);
int v2 = getf(t2);
if( v1 != v2 )
{ //若两个顶点不在同一集合中,这条边加入树
f[v1] = v2;
return 1;
}
return 0;
}
void Kruskal()
{
for( int i = 0; i < m; i++ )
{
if( lian(Q[i].x,Q[i].y) )
{
ans++;
sum = sum + Q[i].z;
if( ans == n-1 ) //当选取n-1条边时最小生成树构造完成
break;
}
}
}
int main()
{
while( ~scanf("%d%d",&n,&m) )
{
for( int i = 0; i < m; i++ )
cin>>Q[i].x>>Q[i].y>>Q[i].z;
sort(Q,Q+m,cmp);
sum = ans = 0;
for( int i = 1; i <= n; i++ )
f[i] = i; //初始化父节点都是本身
Kruskal();
cout<
N-给n个数进行排序-https://vjudge.net/contest/232807#problem/N
题解:水题
#include
#include
using namespace std;
int num[50050];
int main(){
int n;
cin>>n;
for(int i=0;i>num[i];
sort(num,num+n);
for(int i=0;i
O-矩阵相乘-https://vjudge.net/contest/232807#problem/O
题解:这是到题目并不难,直接公式套上去直接AC
#include
#include
using namespace std;
int a[105][105];
int b[105][105];
int main(){
int n;int tmp[105][105]={0};
cin>>n;
for(int i=0;i>a[i][j];
for(int i=0;i>b[i][j];
for(int i=0;i
P-51nod 1283 最小周长-https://vjudge.net/contest/232807#problem/P
题解:就考了一个数学公式,a+b>=2*sqrt(a*b);其实当a==b时,周长最短,因为题意要求
都是整数,我们需要枚举一下就行了
#include
#include
using namespace std;
int main()
{
int s;
cin>>s;
int a=(int)sqrt(s)*100;
a/=100;
for(int i=a;i<=s;i++)
{
if(s%i==0)
{
a=i;
break;
}
}
int b=s/a;
cout<<(b+a)*2<
Q-51nod 1381 硬币游戏-https://vjudge.net/contest/232807#problem/Q
题解:半径为r的硬币相交的直线的的条数有2*r和2*r+1,其中2r+1的情形只有一种就是硬币和直线相切,而硬币落在桌子上的情形有无数种,故概率为0,所以另一种情形的概率是1,所以答案就是2*r
#include
#include
using namespace std;
int main()
{
int s;
cin>>s;
int a=(int)sqrt(s)*100;
a/=100;
for(int i=a;i<=s;i++)
{
if(s%i==0)
{
a=i;
break;
}
}
int b=s/a;
cout<<(b+a)*2<
因为U,V题目基本一样相差一行代码所以直接一起给出题解
U-求A,B最小公倍数-https://vjudge.net/contest/232807#problem/U
V-求A,B最大公约数-https://vjudge.net/contest/232807#problem/V
题解:因为数据范围比较大,直接暴力求会超时,所以需要使用辗转相除法
# include
#include
using namespace std;
int main()
{
long long int a,b,c,x,y;
cin>>a>>b;
x=a;
y=b;
if (a