长春这场我是一个人做的,于是到3个小时的时候我就放弃了……
这场比赛想法提比较多,我看了下题解,想法题一般暴力是能出结果的,但是需要你去简化问题或者简化方法。哪里有那么多的想法,只有无穷多的简化罢了……
还是看题吧:
B - Fraction
这道题的题意就是照着题中的公式计算,一看数据范围就知道是暴力了,计算的方法稍稍模拟下就出来了,一开始没有想对,直接做了除法,wa了几次才反应过来
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
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;
}
D - Triangle
这道题应该是最水的一道题了,题意是从一个1…N的全排列中去掉几个数使得剩下的数中任意三个都不能形成三角形。
首先端这可能需要打表,在找了半天规律之后,终于发现是斐波那契数列,只要判断有多少个小于N的斐波那契数,最后减去就行可以了,原因是因为任意三个斐波那契数之间都不能形成三角形,而且没有特例……这道题算是考了一个逆向思维吧
#include <bits/stdc++.h>
#include <cstring>
#define ll long long
using namespace std;
int a[100];
int cnt[100];
int main()
{
a[1] = 1,a[2] = 2;
for(int i = 3;i<=22;i++)
{
a[i] = a[i-1] +a[i-2];
}
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
//memset(cnt,0,sizeof(cnt));
int n = 0;
int ans = 0;
scanf("%d",&n);
for(int i = 1;i<=20;i++)
{
if(a[i] <= n) ans++;
}
printf("Case #%d: %d\n",cat++,n-ans);
}
return 0;
}
F - Harmonic Value Description
这道题的意思是求出一个排列的相邻两个数的最大公约数的和是第K大的那个排列,有点绕,但是不难理解。
这道题的做法是这样的:首先如果两个数是相邻的,那么他们的GCD肯定是1,一个数X和2*X的GCD是K,那么第K大的排列,说明,2*K和K在最前面,那么将剩下的数输出就行
#include <bits/stdc++.h>
#include <cstring>
#define ll long long
using namespace std;
int main()
{
//ios::sync_with_stdio(0);
int ca,cat = 1;
cin>>ca;
int n,k;
while(ca--)
{
printf("Case #%d: ",cat++);
cin>>n>>k;
printf("%d %d",2*k,k);
for(int i = k-1;i>0;i--)
{
printf(" %d",i);
}
for(int i = k+1;i<=n;i++)
{
if(i != 2*k) printf(" %d",i);
}
printf("\n");
}
return 0;
}
F - Four Operations
这道题的提议是在一个书中间按顺序填上加减乘除四个符号,形成一个表达式,然后求出其中最大的结果。一开始我想的是DFS加剪枝,后来时间原因没写出来。后来和其他人交流的时候发现这是一道贪心……
做法是这样的,因为将一个数变成a+b-c*d/e然后要求最小值,那么我们肯定要让c*d/e的结果最小,让a+b的结果最大,那么我们先给a和b从前往后最大N-3的空间,剩下的位数两位分别给c,d,剩下的就是e了。这个贪心策略是正确的,但是我们会想直接给c,d,e都是一位数,其实不然,譬如111991
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
char str[100001];
int num[100001];
ll getnum(int s,int t)
{
ll res = 0;
for(int i = s;i<=t;i++)
{
res*=10;
res+=num[i];
}
return res;
}
int main()
{
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
scanf("%s",str);
int n = strlen(str);
for(int i = 1;i<=n;i++)
{
num[i] = str[i-1] - '0';
}
ll ans = -INF;
for(int i = 2;i<=n-3;i++)
{
ll c,d,e;
ll add = max(getnum(1,i-1)+getnum(i,i),getnum(1,1)+getnum(2,i));
c = num[i+1],d = num[i+2];
e = getnum(i+3,n);
ans = max(ans,add - c*d/e);
}
printf("Case #%d: %lld\n",cat++,ans);
}
return 0;
}