Pagini recente » Cod sursa (job #1305834) | Cod sursa (job #1934861) | Cod sursa (job #3132058) | Cod sursa (job #1556510) | Cod sursa (job #996128)
Cod sursa(job #996128)
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <string.h>
using namespace std;
/* Note: for some reason, the pp table is computed wrong in index 12 and onwards */
/*
* To check the solutions here's the correct period table
*
* perl -e 'for(1..100){ $s=0; for($j=1;$j<=$_;$j++){ $s += ($j**$j)%10; $s %= 10; }; print "$s,"; }; print "\n"'
*
*/
#define min(x,y) (((x)<(y))?(x):(y))
/*
*
* http://www.infoarena.ro/problema/cifra
*
*/
/*
* phi(10) = phi(2)*phi(5) = 4
* so
* a^4 = 1 mod 10 if (a,n) = 1
*
*
* ^^ this won't help us, so we'll drop math for the moment
*/
class sol {
ifstream I;
ofstream O;
vector<string> v;
vector<vector<int> > p; // period of i^k with i in [0,10]
vector<int> pp; // period of last digit of the sum
int T;
public:
sol() : I("cifra.in") , O("cifra.out") {};
~sol() { I.close(); O.close(); };
void read() {
I >> T;
for(int i=0;i<T;i++) {
string s;
I >> s;
v.push_back(s);
};
};
void precompute_p() {
int i,j;
int mod = 10;
for(i=0;i<10;i++) {
int q=i;
p.push_back(vector<int>());
p[i].push_back(i);
while( (q*i % mod) != p[i][0]) {
q = (q*i) % mod;
p[i].push_back(q);
};
// place last item as first so that
// the index makes sense as a residue mod period
int last = p[i].back();
for(j=p[i].size()-1;j>=1;j--)
p[i][j] = p[i][j-1];
p[i][0] = last;
//cout<<endl;
};
};
void precompute_pp() {
int s = 1;
int i = 2;
pp.push_back(1);
/* I checked this period with OEIS, and it agrees with the first few numbers of the digit, check for yourself
* http://oeis.org/search?q=1%2C5%2C2%2C8%2C3%2C9%2C2%2C8%2C7%2C7%2C8
*
* Also, the period comes out right as well. It's 100
*/
int count[10];
memset(&count,'\x0',10*sizeof(int));
count[s]++;
while(1) {
int ir = i % 10;
int k = p[ir][i % p[ir].size()];
s = (s+k) % 10;
count[s]++;
i++;
pp.push_back(s);
// make sure that all counts are equal
// this means we've reached the end of the period
// (of course this is not entirely correct, would have to do order checking also
// but it's better than hardcoding it, and oeis agrees it's 100 so whatever, it's correct )
int period_reached = 1;
for(int j=1;j<10;j++) {
period_reached &= (count[j] == count[0]);
};
if(period_reached)
break;
};
// same thing as above so that index makes sense
int last = pp.back();
for(int j=pp.size()-1;j>=1;j--)
pp[j] = pp[j-1];
pp[0] = last;
};
void print_periods() {
for(int i=0;i<10;i++) {
for(int j=0;j<p[i].size();j++) {
cout<<p[i][j] << ",";
};
cout<<endl;
};
cout<<"pp="<<endl;
for(int i=0;i<pp.size();i++) {
cout<<pp[i]<<",";
};
cout<<endl;
};
void solve() {
precompute_p();
precompute_pp();
print_periods();
cout<<"ppsize="<<pp.size()<<endl;
for(int i=0;i<v.size();i++) {
int u = 0;
int l2 = atoi(v[i].c_str()+v[i].size() - min(3,v[i].size()) );
//cout <<"l2="<<l2<<endl;
//cout<<"zz="<<pp[l2 % pp.size()]<<endl;
O << pp[l2 % pp.size()]<<endl;
};
};
};
int main() {
sol S;
S.read();
S.solve();
//S.write();
}