哈哈,很久不没写博客了,这次经过大家的努力,学校首次举办程序设计大赛,出了几个水题坑大家,在这也写一篇题解,供感兴趣的童鞋学习,本人是学弱,如有不清楚的地方,可以百度自行解决,本文只是起参考作用,如有错误欢迎指正。
一:过桥,这题数据出了很久了,数据上传oj时没有修改,导致大家在做题时出了点小状况,表示sorry,本题很简单,就只是对字符串的处理,假设用 一个整形变量ans记录结果,读入一个字符串然后扫描该字符串遇到‘w’ ans+=2,遇到‘m’ans+=1,遇到‘m’继续往后扫描就好了,要注意的是,答案是 ans<=30 的,所以如果当前 ans==29 然后下一字符为‘w’便直接结算算法就好了,应为ans+2=31>30。下面是我的代码:
- #include<iostream>
- #include<string>
- using namespace std;
- int main(){
- int T,ans;
- cin>>T;
- string str;
- while(T--){
- cin>>str;
- ans=0;
- for(int i=0;i<str.length() &&ans<=30 ;i++ ){
- if(str[i]=='w' )
- ans+=2;
- if(str[i]=='m' )
- ans+=1;
- }
- if(ans>30)
- cout<<30<<endl;
- else
- cout<<ans<<endl;
- }
- return 0;
- }
二:排序,原本是出的10w个数据,只有用scanf()和printf()输入输出,并且用快排或者堆排序方可通过,但后来考虑坑题已经过多了,这个就不坑大家了就把数据改小了,排序算法我就不多说了,下面是代码,我用了stl里的sort()函数,该函数的具体使用大家可以百度,
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=10005;
int a[maxn];
int main(){
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
printf("%d",a[0]);
for(int i=1;i<n;i++)
printf(" %d",a[i]);
printf("\n");
}
return 0;
}
三:poor dog,这个题是一个经典的深搜问,深搜广搜都能过,网上也有详细的解答
深搜的做法是搜出所有的路径,然后取最短的路径作为衡量标准,
广搜是直接一次广度优先收索找到的路径便是最短路径。
该题输入的是一个邻接矩阵,然后在输入4个整数,这里给出深搜代码:
- #include<iostream>
- #include<stack>
- #define min(a,b) a<=b?a:b
- using namespace std;
- const int maxn=15;
- int n,m;
- int a[maxn][maxn];
- int ans,x2,y2;
- void dfs(int X, int Y, int step) {
- if (X == x2 && Y == y2) {
- ans = min(ans, step);
- return;
- }
- if (a[X][Y]==1 || X < 0 || X == n+1 || Y < 0 || Y == m+1 ) {
- return;
- }
- a[X][Y] = 1;
- step++;
- dfs(X - 1, Y, step);
- dfs(X + 1, Y, step);
- dfs(X,Y + 1, step);
- dfs(X,Y - 1, step);
- a[X][Y] = 0;
- }
- int main(){
- int T;
- cin>>T;
- while(T--){
- ans=999;
- int x1,y1;
- cin>>n>>m;
- for(int i=1;i<=n;i++){
- for(int j=1;j<=m;j++){
- cin>>a[i][j];
- }
- }
- for(int i=0;i<=n+1;i++){
- a[i][0]=1;a[i][m +1]=1;
- }
- for(int i=0;i<=m+1;i++){
- a[0][i]=1;a[n+1][i]=1;
- }
- cin>>x1>>y1>>x2>>y2;
- dfs(x1, y1, 0);
- if(ans>=20){
- cout<<"poor dog"<<endl;
- }
- else{
- cout<<"luck dog"<<endl;
- }
- }
- return 0;
- }
四:单词统计,这个题我觉得是很简单的一个题了,以为很多人回过,数据量不大,即使暴力一个一个统计也能统计出来,当然我的初衷是考考大家map映射容器
定义一个map 就只需要包所有单词扔map容器里,然后在输出就好,代码也很简短:
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
map Mymap;
string str;
while(cin>>str){
Mymap[str]++;
}
map::iterator it;
it=Mymap.begin();
for(;it!=Mymap.end();it++)
cout<< it->first<<":"<< it->second<<endl;
return 0;
}
五:积分,这个题我想直接贴代码算了,就是输入一个函数的系数和指数,如f(x) = 1 + 3x^2 + 2x^4求∫f(x)dx = x + x^3 + (2/5)x^5,估计大家觉得麻烦的就只有化简,求积分就是指数加1,系数除以新指数,这里化简有一个函数 叫 gcd(int a,int b)返回值是a,b的最大公约数,所以 a/gcd(a,b)/ b/gcd(a,b) 及为最简分数了,这里给出代码,代码中有gcd函数的实现,想了解gcd的原理可以百度“辗转相除”
- #include<iostream>
- #include<fstream>
- #include<ctime>
- #include<cstdlib>
- #include<algorithm>
- using namespace std;
- const int maxn=2010;
- int gcd(int a,int b){
- return b==0?a:gcd(b,a%b);
- }
- int main(){
- int a[maxn];
- int T;
- cin>>T;
- while(T--){
- int n;
- cin>>n;
- n*=2;
- for(int i=1;i<=n;i++){
- cin>>a[i];
- }
- for(int i=2;i<=n;i=i+2){
- if(a[i-1]%(a[i]+1) == 0){
- cout<<a[i-1]/(a[i]+1)<<" "<<a[i]+1;
- if(i!=n)
- cout<<" ";
- }
- else{
- if(a[i-1]<0){
- a[i-1]*=-1;
- int tmp=gcd(a[i-1],a[i]+1);
- cout<<"-"<<a[i-1]/tmp<<"/"<<(a[i]+1)/tmp<<" "<<a[i]+1;
- if(i!=n)
- cout<<" ";
- }
- else{
- int tmp=gcd(a[i-1],a[i]+1);
- cout<<a[i-1]/tmp<<"/"<<(a[i]+1)/tmp<<" "<<a[i]+1;
- if(i!=n)
- cout<<" ";
- }
- }
- }
- cout<<endl;
- }
- return 0;
- }
六:tdap的数学,这是一个经典的题目
这两个博客已经讲得非常的清楚了,而且都给出了证明过程,我就不写了,因为数据不一样,下面是我的代码大家可以参考:
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<cstdlib>
- using namespace std;
- typedef long long LL;
- const LL mod=1000000007;
- LL ans;
- struct matrix{
- LL a[3][3];
- }A,B;
- matrix mult2(matrix A,matrix B){
- matrix C;
- for(int i=1;i<=2;i++){
- for(int j=1;j<=2;j++){
- C.a[i][j]=0;
- for(int k=1;k<=2;k++){
- C.a[i][j] = (C.a[i][j] + A.a[i][k]*B.a[k][j])%mod;
- } }
- }
- return C;
- }
- matrix mult(matrix A,LL n){
- if(n==1) return A;
- A = mult(A,n/2);
- if(n%2==0) return A = mult2(A,A);
- return A = mult2(mult2(A,A),B);
- }
- int main(){
- int T;
- int n,a,b,x0,x1;
- LL ans;
- scanf("%d",&T);
- while(T--){
- scanf("%d%d%d%d%d",&n,&a,&b,&x0,&x1);
- if(n==1){
- printf("%d\n",x1);
- continue;
- }
- A.a[1][1]=a;
- A.a[1][2]=b;
- A.a[2][1]=1;
- A.a[2][2]=0;
- B=A;
- A = mult(A,n-1);
- ans = ((A.a[1][1]*x1)%mod + (A.a[1][2]*x0)%mod)%mod;
- printf("%lld\n",ans);
- }
- return 0;
- }
七:魔法,这是线段树,用主席树也可以,这里不详说,有兴趣可以去学习线段树,树状数组,主席树等高级数据结构,这都是很有用的数据结构,这题就直接贴线段树写法的代码吧:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <cmath>
- #include <vector>
using
namespace
std;
- #define lson 2*u
- #define rson 2*u+1
const
int
maxn=100010;
int
n,m;
struct
tnode{
int
l,r,cnt;
int
a[10];
int
getmid(){
return
(l+r)/2;
}
- }tree[4*maxn];
void
build(
int
l,
int
r,
int
u){
tree[u].l=l,tree[u].r=r,tree[u].cnt=0;
memset
(tree[u].a,0,
sizeof
(tree[u].a));
if
(l==r){
return
;
}
int
mid=tree[u].getmid();
build(l,mid,lson);
build(mid+1,r,rson);
- }
void
update(
int
l,
int
r,
int
u,
int
c){
if
(tree[u].l==l&&tree[u].r==r){
tree[u].cnt+=c;
int
Max=min(10,r-l+1);
for
(
int
i=0;i<Max;i++) tree[u].a[i]+=c;
return
;
}
int
mid=tree[u].getmid();
if
(r<=mid) update(l,r,lson,c);
else
if
(l>mid) update(l,r,rson,c);
else
{
update(l,mid,lson,c);
update(mid+1,r,rson,c);
}
int
Max=min(tree[u].r-tree[u].l+1,10);
for
(
int
i=0,j=0,k=0;k<Max;){
if
(tree[lson].a[i]>tree[rson].a[j]) tree[u].a[k++]=tree[lson].a[i++]+tree[u].cnt;
else
tree[u].a[k++]=tree[rson].a[j++]+tree[u].cnt;
}
- }
int
ans[10];
void
query(
int
l,
int
r,
int
u,
int
K){
if
(tree[u].l==l&&tree[u].r==r){
int
Max=min(r-l+1,10);
vector<
int
> v;
for
(
int
i=0;i<Max;i++) v.push_back(tree[u].a[i]+K);
for
(
int
i=0;i<10;i++) v.push_back(ans[i]);
sort(v.begin(),v.end(),greater<
int
>());
for
(
int
i=0;i<10;i++) ans[i]=v[i];
return
;
}
int
mid=tree[u].getmid();
if
(r<=mid) query(l,r,lson,K+tree[u].cnt);
else
if
(l>mid) query(l,r,rson,K+tree[u].cnt);
else
{
query(l,mid,lson,K+tree[u].cnt);
query(mid+1,r,rson,K+tree[u].cnt);
}
- }
int
main()
- {
char
cmd[10];
int
l,r,K;
while
(~
scanf
(
"%d%d"
,&n,&m)){
build(1,n,1);
while
(m--){
scanf
(
"%s%d%d%d"
,cmd,&l,&r,&K);
if
(cmd[0]==
'A'
) update(l,r,1,K);
else
{
memset
(ans,0,
sizeof
(ans));
query(l,r,1,0);
int
tt=0;
for
(
int
i=0;i<K;i++) tt+=ans[i];
printf
(
"%d\n"
,tt);
}
}
}
return
0;
- }
八:谁是赢家,关大神已经证明过了,这直接贴博文链接
- #include<iostream>
using
namespace
std;
int
main(){
int
T;
cin>>T;
while
(T--){
int
m,n;
cin>>n>>m;
if
(n%(m+1)==0)
cout<<
"tdap"
<<endl;
else
cout<<
"xsong"
<<endl;
}
return
0;
- }
九:max sum,这是一道很简单的动态规划,看了代码你一定会的,代码如下:
- #include<iostream>
- using namespace std;
- int main(){
- int n;
- cin>>n;
- while(n--){
- int sum=0;
- int f,k=0,tmp;
- cin>>tmp;
- for(int i=0;i<tmp;i++){
- cin>>f;
- k+=f;
- if(k>sum)
- sum=k;
- if(k<=0)
- k=0;
- }
- cout<<sum<<endl;
- }
- return 0;
- }
其他的题感觉没什么好说的了,有问题可以QQ小刀关大神,或者找本学弱给你粗略讲解