UVA 10036 Divisibility【补充分析】

题目大意:给出数字,要求经过任意加减法(每个数只用一次),输出是否可整除被除数

解题策略:

(a)此题问你是否可以整除。我们知道整除的意思就是余数为0,所以判别是否可以整除,只要判余数是否为0,所以需要做取余数操作。
(b)计算式(10+11)% 3 = (10%3 + 11%3)% 3,其中%表示取余数操作。你可以验算一下,看看这个算式是否成立。
(c)r是余数,队列里存放的都是余数。
(d)在c语言中,(-1)% 3 = -1。这样(1 - 2)%  3 = (-1)% 3 = -1,即余数是负数。
          为了避免负数,我们可以这样计算(1 - 2 + 3)% 3 = 2 % 3 = 2,这条语句r = (cur - temp+ divisor) % divisor;就是这个意思。
          事实上,你课堂上看到,如果不加    divisor,提交到UVa上去后,得到的结果Run Time Error。这是因为当r为负数时,visited[r]的下标就越界了。


/*
   UVA 10036 Divisibility
   AC by J.Dark
   ON 2013/3/27
   Time 0.216s
*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
const int maxn = 10005;
using namespace std;
int Num, divisor, num[maxn];
bool divisible;
vector <bool> visit;

/
void initial(){
     divisible = false;
     divisor = 0;
     //qq.clear();
}

void input(){
     cin >> Num >> divisor; //大数据输入须用scanf,否则会时间很慢
     for(int i=0; i<Num; i++)   cin >> num[i];     
}

void solve(){
     int cur, r, temp, qqsize;
     queue <int> qq;
     qq.push(0);
     //大BFS,一直没掌握,今天好好练练~ 
     for(int i=0; i<Num; i++){
        qqsize = qq.size();
        visit.clear();
        visit.resize(divisor);
        while(qqsize--)
        {
           cur = qq.front();
           qq.pop();
           temp = abs(num[i]) % divisor;
           r = (cur + temp) % divisor;
           if(!visit[r]){  //当前切点是否访问过 
               visit[r] = true;
               qq.push(r); 
           }
           temp = abs(num[i]) % divisor;
           r = (cur - temp + divisor) % divisor; //仔细思考会~ 
           if(!visit[r]){  //当前切点是否访问过 
               visit[r] = true;
               qq.push(r); 
           }                
        } 
     }
     while(!qq.empty()) //若队列不为空
     {
        if(qq.front() == 0){
           divisible = true;
           break;
        }
        else{ qq.pop();}  
     }
     
     if(divisible)
        cout << "Divisible" << endl;
     else
        cout << "Not divisible" << endl;
}
/
int main(){
    int testCase;
    while(cin >> testCase)
    {
       while(testCase--)
       {
           initial();
           input();
           solve();
       }
    }
    //system("pause");
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值