【作业解答】第一次上机作业解题报告

第一题: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;
	}
}

----阿伦                       


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值