第一题:nogre
主要考察基本的字符串读入和文件输入输出流。
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int cnt = 0;
string str;
while(cin>>str){
cnt ++ ;
}
cout<<cnt<<endl;
return 0;
}
ps:carwest这里给大家留了一个坑,如果代码没看也没调试就直接交的同学,这题基本都跪了,我们不忍心看到大家这么跪,还是给大家分了,下次第一题还有坑,大家记得调试一下。
第二题:art
简单的斐波那契,上机时候给大家讲了三种方法:
一、递归写法
二、记忆化写法
三、矩阵快速幂写法
第一种方法的代码就不贴了。。
第二种方法,用数组储存已经计算好的的F(N),避免重复计算,有部分同学还是用用这个方法写的。
#include <iostream>
#include <cstdio>
using namespace std;
int nn, cas;
int ans[10005];
int f(int n)
{
if(ans[n] > 0) return ans[n];
else
{
ans[n] = (f(n-1) + f(n-2)) % 1000000007;
return ans[n];
}
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
cin>>cas;
ans[1] = ans[2] = 1;
while(cas--)
{
cin>>nn;
ans[nn] = f(nn);
cout<<ans[nn]<<endl;
}
}
第三种方法,矩阵快速幂写法,具体什么原理的我就不写了,谷歌 矩阵快速幂+菲波那契数列。
助教标程:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int mod = 100000007;
struct Mat{
long long val[2][2];
void zero(){
memset(val, 0, sizeof(val));
}
}origin, ans;
Mat operator *(const Mat &a, const Mat &b){
Mat res;
res.zero();
for(int k = 0; k < 2; k++){
for(int i = 0; i < 2; i++)
if(a.val[i][k]){
for(int j = 0; j < 2; j++){
res.val[i][j] += a.val[i][k] * b.val[k][j];
if(res.val[i][j] >= mod) res.val[i][j] %= mod;
}
}
}
return res;
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int T, n;
cin>>T;
while(T--){
ans.zero();
ans.val[0][0] = ans.val[1][1] = 1;
origin.zero();
origin.val[0][0] = origin.val[0][1] = origin.val[1][0] = 1;
cin>>n;
while(n){
if(n&1) ans = ans*origin;
n>>=1;
origin = origin*origin;
}
cout<<ans.val[0][1]<<endl;
}
return 0;
}
万宵同学写的也不错,就贴上来啦:
#include<fstream>
#include<iostream>
using namespace std;
class Matrix
{
public:
Matrix(int _a=1,int _b=1,int _c=1,int _d=0):a(_a),b(_b),c(_c),d(_d){}
Matrix operator*(const Matrix& m) const
{
return Matrix(((long long)a*m.a+(long long)b*m.c)%100000007,
((long long)a*m.b+(long long)b*m.d)%100000007,
((long long)c*m.a+(long long)d*m.c)%100000007,
((long long)c*m.b+(long long)d*m.d)%100000007);
}
int ans()
{
return (a+b)%100000007;
}
private:
int a,b,c,d;
};
int main()
{
int sum,num;
Matrix matrix[32];
for(int i=1;i<32;i++) matrix[i] = matrix[i-1]*matrix[i-1];
ifstream fin("in.txt");
ofstream fout("out.txt");
fin>>sum;
for(int i=0;i<sum;i++)
{
Matrix temp(1,0,0,1);
fin>>num;
if(num == 1 || num==2)
{
fout<<1<<endl;
}
else
{
num-=2;
for(int i=0;i<sizeof(int)*8;i++) if(num&(1<<i)) temp = matrix[i] * temp;
fout<<temp.ans()<<endl;
}
}
fin.close();
fout.close();
return 0;
}
第三题:goddess
有点出乎意料,这题竟然很大部分人没得100分,第二题得100分的反而更多,这题其实就是一个简单的循环,但如果你每次都是O(N)的扫一遍,当测试数据很大的话基本都超时,这也是很多人这题只得70分的原因。其实这题有O(1)的方法,其中a[n]表示第1个数到底第n个数的和,当问你一个区间的和的时候,相减一下就行了。。
#include <cstdio>
#include <iostream>
using namespace std;
int K, T, N, M;
int a[100005];
int main()
{
freopen ( "in.txt", "r", stdin );
freopen ( "out.txt", "w", stdout );
cin>>K;
cin>>a[1];
for(int i = 2; i <= K; i++)
{
cin>>a[i];
a[i] += a[i-1];
}
cin>>T;
while(T--)
{
cin>>N>>M;
if(N == M) cout<<a[N] - a[N-1]<<endl;
else cout<<a[M] - a[N-1]<<endl;
}
}
----阿伦