8.11 机房测试
a
问题描述
罗马字母 分别对应着1,5,10,50。其他的字母不允许使用。一个长为 由罗马字母组成的字符串,我们不计顺序地计算它所对应的数值。如 代表35, 代表12。注意 代表11 而不是9。对于长度 的由上述罗马字母组成的字符串最多能代表多少种数值。
数据范围
对于
的数据,
,
对于
的数据,
,
对于
的数据,
。
思路
注意!
该题解中四种权值变成
可以理解为, 长度为n 的字符串, 每个位置都预先放1 在上面。对于同一个数值来说,4 和9 占的比例越小越优,所以
不会超过8 个,
不会超过48 个。
其实就是一道17个for循环打表乱搞轻松AC的水水签到题(一个地方没开long long 少了40分的我失去梦想)
打表程序
#include<bits/stdc++.h>
#define f(i,j,k) for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) for(int k=1;k<=4;k++)
int a[5]={0,1,5,10,50};
bool fl[50000+5];
int main() {
f(q,w,e)f(r,t,y)f(u,i,o)f(p,aa,s)f(d,f,g)f(h,j,k) {
int sum=a[q]+a[w]+a[e]+a[r]+a[t]+a[y]+a[u]+a[i]+a[o]+a[p]+a[aa]+a[s]+a[d]+a[f]+a[g]+a[h]+a[j]+a[k];
fl[sum]=true;
}
int ans=0;
for(int i=1;i<=5000;i++) if(fl[i]) ans++;
printf("%d\n",ans);
}
跑出=18需要10min左右
标程
#include<cstdio>
#include<iostream>
#define FN "a"
int ans[20]={0,4,10,20,35,56,83,116,155,198,244,292,341,390,439,488};
int main() {
freopen(FN".in","r",stdin);
freopen(FN".out","w",stdout);
int n;
scanf("%d",&n);
if(n<=15) printf("%d\n",ans[n]);
else {
long long ANS=1LL*(n-15)*49+488;
printf("%I64d\n",ANS);
}
}
b
问题描述
输入
比较
和
大小
数据范围
对于
的数据,
,
对于
的数据,
,
。
思路
想了很久啷个找规律,结果取个对数一算就TM出来了
天要绝我啊!
有个同学非要写 函数,结果被搞成0分?
比较 和 大小相当于比较 和 的大小
简单明了的想法
但机房有个同学直接比较 大小+特判竟然就A了?
标程
#include<cstdio>
#include<iostream>
#include<cmath>
#define FN "b"
int main() {
freopen(FN".in","r",stdin);
freopen(FN".out","w",stdout);
int T;
scanf("%d",&T);
while(T--) {
int x,y;
scanf("%d%d",&x,&y);
char c;
if(x==y) c='=';
else if(y*log(x)==x*log(y)) c='=';
else if(y*log(x)>x*log(y)) c='>';
else c='<';
printf("%c\n",c);
}
return 0;
}
c
问题描述
两个数a 和b (a < b) 被称为质数相关,是指a×p = b,这里p 是一个质数。一个集合S被称为质数相关,是指S 中存在两个质数相关的数,否则称S 为质数无关。如 质数无关,但 质数相关。现在给定一个集合S,问S 的所有质数无关子集中,最大的子集的大小。
数据范围
集合S 内的数两两不同且范围在1 到500000 之间。
对于
的数据,,
,
对于
的数据,
,
。
思路
首先要做的就是 预处理出是否质数相关
法1:二分图
分解质因数,以质因数个数的奇偶性构建二分图。对于两边的数,如果质数相关就建边。
然后你懂得。
二分图最大独立集。
法2:树形DP
标程:二分图
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
#define maxn 200001
#define mod 10007
#define eps 1e-9
int Num;
char CH[20];
const int inf = 0x3f3f3f3f;
inline ll read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void P(int x) {
Num = 0;
if (!x) {
putchar('0');
puts("");
return;
}
while (x > 0)
CH[++Num] = x % 10, x /= 10;
while (Num)
putchar(CH[Num--] + 48);
puts("");
}
const int MAXN = 500001;
bool flag[MAXN];
int primes[MAXN], pi;
void GetPrime_1() {
int i, j;
pi = 0;
memset(flag, false, sizeof(flag));
for (i = 2; i < MAXN; i++)
if (!flag[i]) {
primes[i] = 1;
for (j = i; j < MAXN; j += i)
flag[j] = true;
}
}
vector<int> q[maxn];
int vis[maxn];
int match[maxn];
int a[maxn];
bool cmp(int b, int c) { return b > c; }
int dfs(int x) {
for (int i = 0; i < q[x].size(); i++) {
if (vis[q[x][i]] == 0) {
vis[q[x][i]] = 1;
if (match[q[x][i]] == -1 || dfs(match[q[x][i]])) {
match[q[x][i]] = x;
return 1;
}
}
}
return 0;
}
int main() {
freopen("c.in", "r", stdin);
freopen("c.out", "w", stdout);
GetPrime_1();
primes[1] = 0;
int t = read();
for (int cas = 1; cas <= t; cas++) {
memset(match, -1, sizeof(match));
int n = read();
for (int i = 0; i < n; i++)
q[i].clear();
for (int i = 0; i < n; i++)
a[i] = read();
sort(a, a + n, cmp);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == j)
continue;
int b = a[j];
int c = a[i];
if (b < c)
swap(b, c);
if (b % c == 0 && primes[b / c]) {
q[j].push_back(i);
}
}
}
int ans = 0;
for (int i = 0; i < n; i++) {
memset(vis, 0, sizeof(vis));
if (dfs(i))
ans++;
}
printf("%d\n", n - ans / 2);
}
}
总结(讲垃圾话)
一二题其实都很蠢(但是我每道题都玩掉了40分)
三题不算难。
看着佘刀AK虐场只能望洋兴叹。
Doggu学长对我们提出的几点期望,我竟然完美的完全没有做到。
还有90天就是NOIP了,希望自己脚踏实地,砥砺奋斗,踏浪前行。