0

Consider a very long K-digit number N with digits d0, d1, ..., dK-1 (in decimal notation; d0 is the most significant and dK-1 the least significant digit). This number is so large that we can't give it to you on the input explicitly; instead, you are only given its starting digits and a way to construct the remainder of the number.

Specifically, you are given d0 and d1; for each i ≥ 2, di is the sum of all preceding (more significant) digits, modulo 10 — more formally, the following formula must hold:

enter image description here

Determine if N is a multiple of 3.

Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows. The first and only line of each test case contains three space-separated integers K, d0 and d1.
Output
For each test case, print a single line containing the string "YES" (without quotes) if the number N is a multiple of 3 or "NO" (without quotes) otherwise.

Constraints 1 ≤ T ≤ 1000
2 ≤ K ≤ 1012
1 ≤ d0 ≤ 9
0 ≤ d1 ≤ 9
Example
Input:
3
5 3 4
13 8 1
760399384224 5 1

Output:
NO
YES
YES
Explanation
Example case 1: The whole number N is 34748, which is not divisible by 3, so the answer is NO.

Example case 2: The whole number N is 8198624862486, which is divisible by 3, so the answer is YES.

Question Ended

In this question, in the example test case given, we have k=760399384224, d0=5, and d1=1. Now we know that a number is multiple of 3 if the sum of it’s digits is a multiple of 3. So applying it here, we separate the number n into 3 parts,
Part 1: First 3 digits -> 516 , (5+1+6) mod 3 ==0, so rem1 = 0.
Part 2: Next will be (k-3)/4 times repetition of (2486) ,or,rem2 = ((2+4+8+6)*((k-3)/4))%3= 1
Part 3: the last (k-3)%4 =1 digits which will be 2 (from 2486 repetition) , so rem3 = 2%3=2
So the final answer should be (rem1+rem2+rem3)%3

and I wrote the following code for this logic:

#include<iostream>
#define ll long long
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
         ll k;
         cin>>k;
         int d0,d1;
         cin>>d0>>d1;
         int d2 = (d0+d1)%10;
         int d[4];
         d[0] = (d0+d1+d2)%10;
         d[1] = (2*d[0])%10;
         d[2] = (2*d[1])%10;
         d[3] = (2*d[2])%10;
         ll rem1 = (d0+d1+d2)%3,rem2,rem3=0;
         rem2 = (20*(((k-3)/4)%3))%3;
         ll x = (k-3)%4;
         if(x!=0)
         {
            for(int i=0; i<x; ++i)
            rem3+=d[i];
            rem3 = rem3%3;
         }
         else
             rem3 =0;
         if(k==2)
         {
             rem1 = (d0+d1)%3;
             rem2=0;
             rem3=0;
         }
         if((rem1+rem2+rem3)%3==0)
            cout<<"YES"<<endl;
         else
            cout<<"NO"<<endl;
    }
}


Now they’re giving me WA in their test cases. And I cant think of a possible test cases which doesn’t work with this code. So somebody help me out please.

Yash Singh
  • 11
  • 6
  • 1
    following your link I cannot view the problem description. Please make your quesiton self contained by including the problem description – 463035818_is_not_an_ai Sep 10 '20 at 11:13
  • worth reading: [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) and `#define ll long long` is just bad taste imho – 463035818_is_not_an_ai Sep 10 '20 at 11:15
  • @idclev463035818 Yes but I thought it would be easier to read the problem from the link because they have structured it better than I would. And I've heard about the bad practices but didn't know that '#define ll long long' was a bad taste, I just read it somewhere and thought it's a good way to make things shorter – Yash Singh Sep 10 '20 at 11:23
  • why is it desirable to make things shorter? Some clever ppl put some thought into naming the type `long long`. If you want to declare a variable of type `long long` you can write `long long`. I really don't see how `ll` makes it any clearer, it rather makes it less readable. For the link: I cannot open that page, hence I cannot know what problem your code is trying to solve – 463035818_is_not_an_ai Sep 10 '20 at 11:26
  • @idclev463035818 There, I included the whole question – Yash Singh Sep 10 '20 at 11:45
  • @גלעדברקן Trying to think because the code gives correct answer for general inputs, but there might be some corner-case where something might be going wrong – Yash Singh Sep 10 '20 at 11:47
  • @idclev463035818 You are right but long long is present in every other question ,so it kind of helps i guess – Yash Singh Sep 10 '20 at 11:52
  • `using namespace std;` is also present in too many code, yet it does not help, in fact it can to great harm. Don't do stuff just because someone else does it, know what are the consequences, then make a decision. For me the issue is rather clear: `long long` -> everybody knows what it is, easy to read, `ll` -> could in principle be anything (i have even seen `#define ll int` *shudder*), not very readable – 463035818_is_not_an_ai Sep 10 '20 at 11:57

2 Answers2

0

Here's an apparent mismatch. You can probably use this JavaScript code to find more:

function f(k, d0, d1){
  let d2 = (d0+d1)%10;
  let d = new Array(4).fill(0);
  d[0] = (d0+d1+d2)%10;
  d[1] = (2*d[0])%10;
  d[2] = (2*d[1])%10;
  d[3] = (2*d[2])%10;
  let rem1 = (d0+d1+d2)%3, rem2, rem3=0;
  rem2 = (20*((~~((k-3)/4))%3))%3;
  let x = (k-3)%4;
  if(x!=0)
  {
    for(let i=0; i<x; ++i)
    rem3+=d[i];
    rem3 = rem3%3;
  }
  else
      rem3 =0;
  if(k==2)
  {
      rem1 = (d0+d1)%3;
      rem2=0;
      rem3=0;
  }
  if((rem1+rem2+rem3)%3==0)
    return true

  return false
}

function bruteForce(k, d0, d1){
  let d = (d0 + d1) % 10;
  let n = 10 * d0 + d1;
  for (let i=3; i<=k; i++){
    n = 10 * n + d;
    d = (2 * d) % 10;
  }
  return [n % 3 == 0, n];
}

let str = "";

str += "Examples:\n";
str += "(5, 3, 4)\n" + bruteForce(5, 3, 4) + "\n\n";
str += "(13, 8, 1)\n" + bruteForce(13, 8, 1) + "\n\n"

var k = 7;
var mismatch = false;

for (let i=1; i<10; i++){
  for (let j=0; j<10; j++){
    const _f = f(k, i, j);
    const _bruteForce = bruteForce(k, i, j);

    if (_bruteForce[0] != _f){
      str += "Mismatch:\n" + 
        `(${ k }, ${ i }, ${ j })\n` +
        "f: " + _f +
        "\nbruteForce: " + _bruteForce + "\n\n";
      mismatch = true;
    }
    if (mismatch)
      break;
  }
  if (mismatch)
    break;
}

console.log(str);
גלעד ברקן
  • 23,602
  • 3
  • 25
  • 61
0
#include <stdio.h>

void isMulti3(long long int K, long long int d0, long long int d1) {
    long long int mod1 = (d0 + d1) % 10;

    long long int sum_mod1 = d0 + d1 + mod1;
    
    long long int rep = (K-3)/4;
    long long int mod2[4];
    mod2[0] = (2*mod1) % 10;
    mod2[1] = (4*mod1) % 10;
    mod2[2] = (8*mod1) % 10;
    mod2[3] = (6*mod1) % 10;

    long long int sum_mod2 = 0;
    for(int i = 0; i < 4; i++) {
        sum_mod2 += mod2[i];
    }

    long long int unrep = (K - 3) % 4;
    long long int sum_mod3 = 0;
    for(int i = 0; i < unrep; i++) sum_mod3 += mod2[i]; 
    long long int isMod1 = sum_mod1 % 3;
    long long int isMod2 = ((rep%3)*(sum_mod2%3)) % 3;
    long long int isMod3 = sum_mod3 % 3;

    if((isMod1 + (isMod2 + isMod3)%3)% 3 == 0) printf("YES\n");
    else printf("NO\n");

}
int main() {
    int T;
    scanf("%d", &T);

    for(int i = 0; i < T; i++) {
        long long int K;
        long long int d0, d1;
        scanf("%lld %lld %lld", &K, &d0, &d1);
        if(K == 2) {
            if((d0 + d1) % 3 == 0) printf("YES\n");
            else printf("NO\n");
        }
        else isMulti3(K, d0, d1);


    }
}

I think you are the same guy who asked the question on the codechef discussion portal. I answered it there , and I am sharing the link. [https://discuss.codechef.com/t/dsa-learning-series-multiple-of-3/77174/4?u=nazishkaunain][1] So the point where you are mistaken is:

You might use the fact: (a+b+c)mod 3 != a mod 3 + b mod 3 + c mod 3; But (a + b + c) mod 3 = (a mod 3 + ( b mod 3 + c mod 3) mod 3) mod 3; And a number n ( n = a + b + c) is divisible by 3 only if n mod 3 = 0 => (a + b + c) mod 3 = 0.