Pagini recente » Cod sursa (job #1818587) | Cod sursa (job #2831527) | Cod sursa (job #1303888) | Cod sursa (job #312798) | Cod sursa (job #502103)
Cod sursa(job #502103)
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
using namespace std;
#define FILE_IN "cifra.in"
#define FILE_OUT "cifra.out"
/*
* Insight: In mod evident, (N^N) % 10 = ((N%10)^N) % 10.
* In timpul constructiei tabelei de a^b cu a,b=0..10 se constata
* si ca (N^K) % 10 = (N^(K+4)) % 10 pentru K>0. De aici rezulta ca:
*
* (N^N) % 10 = ((N+40)^(N+40)) % 10
*
* deci sirul 1^1+2^2+... e periodic; se calculeaza suma unei perioade
* ca fiind 8, deci calculul sumei se face din (N/40)*suma perioada + suma
* manuala pentru restul termenilor.
*/
int POW[10][11];
int T;
char N[200];
void initPow()
{
for (int i=0; i<10; i++)
{
POW[i][0] = i ? 1 : 0;
for (int j=1; j<=10; j++) POW[i][j] = (POW[i][j-1]*i)%10;
}
}
int nLaN(int n)
{
int pw = n%4;
return POW[n%10][pw ? pw : 4];
}
int div40(char* n)
{
// imparte cu 4
int rest = 0;
char* ptr = n;
while (*ptr)
{
rest = rest*10 + (*ptr-48);
*ptr = 48 + (rest/4);
rest = rest % 4;
ptr++;
}
// imparte cu 10
rest = (*(--ptr)-48)*4 + rest;
*ptr = 0;
if (ptr == n) *ptr = '0';
return rest;
}
int main()
{
initPow();
ifstream fisIn(FILE_IN);
ofstream fisOut(FILE_OUT);
fisIn >> T;
fisIn.getline(N, 2); // treci la lina urmatoare
for (int i=0; i<T; i++)
{
fisIn.getline(N, 200);
int rest = div40(N);
int suma = (8*(N[strlen(N)-1]-48)) % 10; // suma perioadelor
for (int j=1; j<=rest; j++) suma = (suma + nLaN(j)) % 10;
fisOut << suma << "\n";
}
}