题目都是水题,但是我是水人啊,疯狂水,啥也不会,故很多做不出来,说是大一就参加了acm,可实际上,大二下学期期末,才开始做题,以前基本不碰代码;故,现在被大一的,吊在胯里打;
A题:http://poj.org/problem?id=3070
题意:求斐波那契的后4位数,此题矩阵快速幂,哈哈哈,不会;不过后来看了下,这题好像就比快速幂多个矩阵而已(都是简单模板而已啊);当时没做出来;
ps;快速幂水题,不解释了,放个代码,留个纪念;
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stdio.h>
using namespace std;
typedef long long int ll;
struct pp {
ll a[2][2];
void init() {
a[0][0]=0;
a[0][1]=a[1][1]=a[1][0]=1;
}
};
pp mutrixul(pp b,pp c,ll n) {
pp ans;
//ans.init();
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
ans.a[i][j]=0;
for(int k=0; k<n; k++) {
ans.a[i][j]+=b.a[i][k]*c.a[k][j];
}
ans.a[i][j]%=10000;
}
}
return ans;
}
pp mul(pp b,ll n) {
pp ans,cnt=b;
ans.init();
while(n) {
if(n&1) {
ans=mutrixul(ans,cnt,2);
}
cnt=mutrixul(cnt,cnt,2);
n>>=1;
}
return ans;
}
int main() {
ll n;
while(cin>>n&&n!=-1) {
if(n!=0) {
pp s;
s.init();
s=mul(s,n-1);
cout<<s.a[1][0]%10000<<endl;
}
else
printf("0\n");
}
}
B题:http://codeforces.com/problemset/problem/574/C
当时看错题意了,居然也没做出来,不太难的一道思维题;
ps:就是看他们有没有可能约到一个数;
D题:http://codeforces.com/problemset/problem/1064/B
题意:求满足a-(a^x)-x=0有多少个这样的x;
ps:实际上就是看有多少个1,只要对应1的位置来个1,就成立;故假设有N个1答案为2的n次方;
也就是说,0变为0,对齐1的变为0,所以等互补了,故成立;
#include <iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
long long int poww(int x,int y){
long long int res=x,ans=1;
while(y){
if(y&1){
ans=(ans*res);
}
res*=res;
y>>=1;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--){
int a,ans=0;
cin>>a;
if(a==0){
cout<<'1'<<endl;
continue;
}
while(a){
if(a%2!=0)ans++;
a/=2;
}
//double cnt=pow(2,ans);
int cnt = poww(2,ans);
cout <<(int)cnt<< endl;
}
return 0;
}
E题:http://acm.hdu.edu.cn/showproblem.php?pid=6286
题意:给定两个区间ab,cd;求此区间内有多少个相乘为2018倍数的个数;
ps:1:2018的倍数的数,乘任何数都满足,1009乘任何偶数倍都满足;
故:先求a-b,2018倍数的个数,乘c-d区间,然后c-d2018倍数乘a-b区间,此时有2018*2018,这种数重合了,因为两边相等,所以反过来也是一个数;故要减去 2018的倍数*2018的倍数,把重合是数减掉;
然后求1009的数和另一边的偶数的个数,然后要去掉,偶数中2018的数的个数;即为答案
#include <iostream>
using namespace std;
typedef long long int ll;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
ll a,b,c,d;
while(cin>>a>>b>>c>>d){
ll a1,a2,sum=0;
a1=b/2018-a/2018; // 第一区间2018个数
if(a%2018==0)a1++;
a2=d/2018-c/2018; //第二区间2018个数
if(c%2018==0)a2++;
sum+=a1*(d-c+1)+a2*(b-a+1)-a1*a2; //最后减去 重合部分:2018*2018,4056*4056,此数;
ll p1,p2;
p1=b/1009-a/1009; //1009个数
if(a%1009==0)p1++;
p2=d/1009-c/1009;
if(c%1009==0)p2++;
ll t1,t2;
t1=p1-a1; //1009总个数-2018个数就是1009奇数倍
t2=p2-a2;
ll q1,q2;
q1=d/2-c/2;
if(c%2==0)q1++;
q2=b/2-a/2;
if(a%2==0)q2++;
sum+=t1*(q1-a2)+t2*(q2-a1);
cout << sum<< endl;
}
return 0;
}
F题:http://codeforces.com/problemset/problem/1058/D
题意:在m,n,内找一个面积为m*n/k的三角形;
ps;因为将一点固定在原点,根据坐标三角形面积公式,行列式可求,s=x2y3-x3y2=2*m*n/k;因为x2,y2,x3,y3全部为整数,所以m*n/k也要是整数;
求解n1,m1,当k为偶数时,直接,k=/2,n1=n/gcd(n,k),k'=k/gcd(n,k);m1==m/k'==m1==m*gcd(n,k)/k;
若为奇数,则看gcd(n,k)》=2,如果大于,直接n1*=2;因为*2也不会大于n;
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stdio.h>
using namespace std;
typedef long long int ll;
ll gcd(ll x, ll y) {
return x%y==0?y:gcd(y,x%y);
}
int main() {
ll n,m,k;
cin>>n>>m>>k;
if(2*n*m%k==0) {
ll n1,m1;
if(!(k&1)) {
k/=2;
n1=n/gcd(n,k);
m1=m*gcd(n,k)/k;
} else {
n1=n/gcd(n,k);
m1=m*gcd(n,k)/k;
if(gcd(n,k)>=2)n1*=2;
else m1*=2;
}
printf("YES\n");
printf("%d 0\n",n1);
printf("0 %d\n",m1);
printf("0 0\n");
}
else
printf("NO\n");
return 0;
}