zoukankan      html  css  js  c++  java
  • 51nod 1346:递归

    基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
     收藏
     关注

    函数f(n,m)

    {

    若n=1或m=1返回a[n][m];

    返回f(n-1,m)异或f(n,m-1);

    }

    读入2<=n,m<=100

    for i=2->100读入a[1][i]

    for i=2->100读入a[i][1]

    输出f(n,m)

     

    发现当n,m较大时程序变得异常缓慢。

    小b经过一番思考,很快解决了这个问题。

    这时小c出现了,我将n,m都增加131072,你还能解决吗?

    相对的,我会读入2->131172的所有a[1][i]和a[i][1]。

    小b犯了难,所以来找你,你能帮帮他吗?

    Input
    第一行读入131171个正整数,表示i=2->131172的a[1][i](1<=a[1][i]<=1000000000)。
    第二行读入131171个正整数,表示i=2->131172的a[i][1](1<=a[i][1]<=1000000000)。
    第三行读入一个正整数Q(1<=Q<=10000),表示询问的次数。
    接下来Q行,每行两个数n,m(2<=n,m<=100),表示每一组询问。
    Output
    Q行,每行为f(n+131072,m+131072)
    Input示例
    2 3 4 5 6 7 8 … 131171 131172
    2 3 4 5 6 7 8 … 131171 131172
    3
    2 2
    2 3
    2 4
    Output示例
    0
    0
    131072

    a[i][j]=a[i-1][j]^a[i][j-1]=a[i-2][j]^a[i-1][j-1]^a[i-1][j-1]^a[i][j-2]=a[i-2][j]^a[i][j-2]

    a[i][j]=a[i-2][j]^a[i][j-2]=a[i-4][j]^a[i-2][j-2]^a[i-2][j-2]^a[i][j-4]=a[i-4][j]^a[i][j-4]

    以此类推可以发现

    a[i][j]=a[i-131072][j]^a[i][j-131072]

    预处理a[1..100][1..131172]与a[1..131172][1..100]

    对于每个询问答案即为a[n][131072+m]^a[131072+n][m]


    觉得51nod的题目真的很有趣,当然如果它的数学题没那么难的话我会觉得更有趣。

    当时做的时候已经逐渐地推出来规律了,但是自己读题的能力上真的有欠缺,然后另一点,就是感觉预处理会超时,就没敢那么做,觉得会不对(怕什么啊,做一下再说啊)

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstring>
    #pragma warning(disable:4996)
    using namespace std;
    
    int a1[131175];
    int a2[131175];
    
    int r1[105][131175];
    int r2[131175][105];
    
    int main()
    {
    	int i,m,n,Q;
    
    	a1[1] = 0;
    	a2[1] = 0;
    	memset(r1, 0, sizeof(r1));
    	memset(r2, 0, sizeof(r2));
    
    	for (i = 2; i <= 131172; i++)
    	{
    		scanf("%d",&a1[i]);
    		r1[1][i] = a1[i];
    		if (i >= 2 && i <= 100) r2[1][i] = a1[i];
    	}
    	for (i = 2; i <= 131172; i++)
    	{
    		scanf("%d", &a2[i]);
    		r2[i][1] = a2[i];
    		if (i >= 2 && i <= 100) r1[i][1] = a2[i];
    	}
    	for (m = 2; m <= 100; m++)
    	{
    		for (n = 2; n <= 131172;n++)
    		{
    			r1[m][n] = r1[m - 1][n] ^ r1[m][n - 1];
    		}
    	}
    	for (m = 2; m <= 131172; m++)
    	{
    		for (n = 2; n <= 100; n++)
    		{
    			r2[m][n] = r2[m - 1][n] ^ r2[m][n - 1];
    		}
    	}
    	scanf("%d", &Q);
    	for (i = 1; i <= Q; i++)
    	{
    		scanf("%d%d", &n, &m);
    		cout << (r1[n][131072 + m] ^ r2[131072 + n][m])<< endl;
    	}
    
    	return 0;
    }
    





    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    微信小程序上拉分页
    关于检测数据类型,三种方法(typeof,instanceof,Object.prototype.toString.call())优缺点
    如何在Devc++中配置OpenCv
    数据库系统和应用
    这是一篇测试文档
    Pandas 表格合并
    es6一些好用的方法总结
    前端面试题
    超有趣! JS是怎么计算1+2!!!
    彻底理解闭包
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4785760.html
Copyright © 2011-2022 走看看