B - Fraction
温暖的签到,求一个奇奇怪怪的式子的解。
不能用除法,我们手写几次就会发现上一次的分子分母交换一下就可以,最后记得约分
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
int a[20],b[20];
int gcd(int a,int b)
{
return a == 0 ? b: gcd(b%a,a);
}
int main()
{
//ios::sync_with_stdio(false);
// freopen("input.txt","r",stdin);
//scanf("%d",&T);
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
int n = 0;
scanf("%d",&n);
for(int i = 1;i<=n;i++) scanf("%d",&a[i]);
for(int j = 1;j<=n;j++) scanf("%d",&b[j]);
int p = b[n],q = a[n];
for(int i = n-1;i>0;i--)
{
p += a[i] * q;
q*=b[i];
swap(q,p);
}
int t = gcd(q,p);
printf("Case #%d: %d %d\n",cat++,p/t,q/t);
}
return 0;
}
一年之前,我还会这种巧妙地办法。
当然还有一种暴力的做法,写一个分数类
#include <iostream>
#include <algorithm>
using namespace std;
struct num
{
int a,b;
num(){}
num(int _a,int _b)
{
int gcd = __gcd(_a,_b);
a = _a/gcd,b = _b/gcd;
}
num operator + (const num &y) const
{
return num(y.b*a+y.a*b,b*y.b);
}
num operator / (const num &y) const
{
return num(a*y.b,b*y.a);
}
void reduce()
{
int gcd = __gcd(a,b);
a = a/gcd,b = b/gcd;
}
};
int a[101],b[101];
int main()
{
int ca,cat = 1;
cin>>ca;
while(ca--)
{
int n;
cin>>n;
for(int i = 1;i<=n;i++)
{
cin>>a[i];
}
for(int i = 1;i<=n;i++)
{
cin>>b[i];
}
num ans = num(a[n],1);;
for(int i = n;i >= 1;i--)
{
if(i == 1) ans = num(b[i],1)/ans;
else ans = num(a[i-1],1)+(num(b[i],1)/ans);
ans.reduce();
//cout<<ans.a<<' '<<ans.b<<endl;
}
cout<<"Case #"<<cat++<<": "<<ans.a<<' '<<ans.b<<endl;
}
return 0;
}
D - Triangle
把一个从1到n的序列拿出最少的一部分数,让剩下的数形不成三角形。
想到 :a+b == c 只要将fib数留下来就行了,这样任意两个数加起来都是<=c 的
F - Harmonic Value Description
构造题,首先第k大的值是n+k-2。我们根据这个构造一下,分成奇偶分开排列就行了
H - Sequence I
看出来是要用kmp了,发现不用动b串,我们枚举每次匹配的开头,然后按照间隔p进行匹配就行了,因为只匹配p次,时间复杂度O(能过)
或者将a数组每次采样,然后kmp,时间是一样的
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define next fuck
using namespace std;
const int MAXN = 1e6 + 10;
int next[MAXN],a[MAXN],b[MAXN];
int p;
void pre(int x[],int m)
{
memset(next,0,sizeof(next));
int i,j;
j = next[0] = -1;
i = 0;
while(i <=m)
{
while(-1 != j && x[i] != x[j])
j = next[j];
next[++i] = ++j;
}
}
int kmp(int x[],int m,int y[],int n)
{
int i,j;
int ans = 0;
pre(x,m);
for(int ii = 0;ii<p;ii++)
{
i = ii;
j = 0;
int pos = 0;
while(i < n)
{
while(-1 !=j && y[i] != x[j])
j = next[j];
i+=p,j++;
if(j >= m)
ans++,j = next[j];
}
}
return ans;
}
int main()
{
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
int n,m;
scanf("%d%d%d",&n,&m,&p);
for(int i = 0;i<n;i++) scanf("%d",&a[i]);
for(int i = 0;i<m;i++) scanf("%d",&b[i]);
int ans = 0;
if(m > n/p) ans = 0;
else ans = kmp(b,m,a,n);
printf("Case #%d: %d\n",cat++,ans);
}
return 0;
}
J - Ugly Problem
最近写了不少java,手基本熟了,可以转型java选手了
我们把一个数切成两半,前一半构造一个回文串,然后接着处理剩下的数字,这里要分成奇数偶数判断一下,同时要注意1000这样的特例
import java.lang.*;
import java.math.BigInteger;
import java.util.Scanner;
import java.util.Vector;
public class Main {
static Vector<String> vec;
public static void dfs(String s)
{
BigInteger rs = new BigInteger(s);
int len = s.length();
if(len == 1)
{
vec.add(s);
return ;
}
if(rs.subtract(BigInteger.ONE).toString().length() < len)
{
vec.add(rs.subtract(BigInteger.ONE).toString());
vec.add("1");
return;
}
String l = s.substring(0, len/2);
String r = s.substring(len/2+(len %2),len);
String res = "";
if(rev(l).compareTo(r) <= 0)
{
res= l;
if(len % 2 == 1)
{
res = res + s.charAt(len/2);
}
res = res + rev(l);
}
else
{
res = l;
if(len % 2 == 1)
{
res = res + s.charAt(len/2);
res = (new BigInteger(res).subtract(BigInteger.ONE)).toString();
res =res + rev(res.substring(0,len/2));
}
else
{
res = (new BigInteger(res).subtract(BigInteger.ONE)).toString();
res = res + rev(res);
}
//else res = res+"99"+ res;
}
vec.add(res);
rs = rs.subtract(new BigInteger(res));
//System.out.println(rs);
if(rs.compareTo(BigInteger.ZERO) == 0) return;
dfs(rs.toString());
return;
}
public static String rev(String s)
{
StringBuilder sb = new StringBuilder(s);
sb.reverse();
return sb.toString();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int ca = sc.nextInt(),cat = 1;
vec = new Vector<String>();
while(ca-- != 0)
{
String s = sc.next();
vec.clear();
dfs(s);
System.out.printf("Case #%d:\n%d\n",cat++,vec.size());
for(String vs : vec)
{
System.out.println(vs);
}
}
}
}