前言
HL第一次考试
寄了,记一下(doge
题目如下
题目
T1:挂
绩点是衡量大学生学业成绩的一个指标,在某所大学里,绩点是这么计算的:
设一门课的成绩转化为百分制之后为x,定义这门课的绩点g如下:
1、当x<60时,定义g=0.00
2、否则定义g=4-3*(100-x)^2/1600,然后四舍五入到两位小数。
在此计算方式下,可以知道60分对应的绩点就是1.00,90分对应的绩点是3.81,99和100分对应的绩点都是4.00。
同时,每门课还有一个学分s,定义若干门课的平均绩点为这些课的绩点以学分为权重进行加权平均,再四舍五入到两位小数所得的结果。
现在你的任务就是计算若干位同学在一学期内所有课程的平均绩点。
输入格式 第一行为一个正整数T,表示数据组数
接下来T组数据,每组数据第一行为一个正整数n,表示某位同学某学期所报的课程数,接下来n行,每行两个整数s,x,表示这位同学这学期学习了一门学分为s的课程,取得的成绩在百分制下为x。
输出格式 对每组数据输出一行一个两位小数,表示这组数据对应的课程的平均绩点。
样例 input
2
3
11 60
1 100
12 100
6
4 81
5 85
2 88
2 88
2 76
5 87
样例 output
2.63
3.52
对于50%的数据,输入中所有百分制的分数为60或100。
对于100%的数据,1<=T<=1000,1<=n<=50,1<=s<=12,0<=x<=100
样例解释
第一组数据加权平均绩点为(11+13*4)/24=2.625,四舍五入输出2.63。
T2:AC
题目 给定 m 个不同的正整数 a1, a2, …, am,请对 0 到 m 每一个 k 计算,在区间 [1, n] 里有多少正整数是 a 中恰好 k 个数的约数。
对于 100 100%100 的数据,m ≤ 200 , n , a i ≤ 1 0 9 m ≤ 200, n,ai ≤ 10^9m≤200,n,ai≤10 9 。
分析 30pts暴力随便写,时间复杂度O ( n m ) O(nm)O(nm)
100pts正解
把m个数约数求出来,然后排序去重操作,只有这些约数才会对答案产生贡献,将这些约数求出答案
当k = 0 k=0k=0时,a n s [ k ] = n − ∑ i = 1 m a n s [ i ] ans[k]=n-\sum_{i=1}^m ans[i]ans[k]=n−∑ i=1 mans[i]
样例
就挺水的……
T3:AC
⼩ Y 同学有⼀块超级 CPU,它有两个超级核⼼ A 和 B。 A 核⼼可以同时处理多项任务,每项任务处理时间为 x,B 核⼼只能同时 处理⼀项任务,每项任务处理时间为 y。 这⼀天,⼩ Y 同学接到了 n 项紧急任务,第 i 项紧急任务在 ti 时刻发出, 且必须在任务发出时进⾏处理。 由于⼩ Y 可以调节 CPU 的 B 核⼼,你想知道对于 y ∈ [1, x](即 y 从 1 到 x 依次取值),处理完毕所有任务的最早时间是多少?
样例:同前一样的水
T4:AC
给定 n 个正整数,每个正整数的大小不超过 40 40。
可以执行任意次操作,每次操作可以选取两个相邻且相同的数字,并将他们合并,合并后的数字为合并前的数字 +1。
求最后这些数字的最大值最多可以是多少。
样例:我***
T5:挂 给定
n 个点
m 条边的有向图,问从 1 1 号点出发并回到 1 1 号点,最多能访问到多少个不同的点。过程中可以重复经过任意点。
这题实在太简单了,于是我们允许在行走过程中可以有一次行走是沿一条边逆向而行的,问在这种情况下最多能访问到多少个不同的点。
这个题名是足够逆天的,可以。
可以骗1分,但我不说(bushi
T6:挂
你现在处于一个二维平面中,在 0 0 时刻你位于起始点 ( 0 , 0 ) (0,0)。若某一时刻你处于位置 (x,y),那么你可以选择在下一时刻出现在
(x,y),
(x+1,y),
(x−1,y),
(x,y+1)
四个位置中的任意一个。
系统发布了若干个任务:若在第 T 时刻你位于点 (X,Y),你将获得 W 的奖励。
求最大收益。
OI高中后第一次考试吧,301分,刚拿一半分,挺难评的。让小学的王者们按在地上摩擦。
代码
解析给的解释真好,一下就透了
下午订正了,算是AK?
但是T6成功被雪猫唤醒了我的惰性,这是能说的吗??
T1
注意仔细阅读题面以及四舍五入时的误差
没出来也是够@!*@的……
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin >> T;
for(int d = 1;d <= T;d ++)
{
int n,s[52] = {},x[52] = {};
cin >> n;
int ssum = 0;
double gsum = 0;
for(int i = 1;i <= n;i ++)
{
cin >> s[i] >> x[i];
ssum += s[i];
}
for(int i = 1;i <= n;i ++)
{
if(x[i] < 60)
{
continue;
}
else
{
double g = (4.0 - 3.0 * (100.0 - double(x[i])) * (100.0 - double(x[i])) / 1600.0);
gsum += round(g *100) * s[i];
}
}
printf("%.2lf\n",0.01 * round(gsum / ssum));
}
return 0;
}
T2
基础数论?一如既往的好玩,这是实话(请不要让我出去
对于前 30 的分数,直接 O(nm) 判断并计数即可。 对于中间的 30 分,只需求出 a1 有多少个约数。
对于满分做法,注意到可以求出所有 k>0 的答案,用 n 减去这些值就能算出 k=0 的结果。于是对每个输入的 ai 根号求出所有约数,借助 map 即可实现快速计数。
如果不使用 STL 也可以将所有约数求出来,sort 一下之后对每个不同的约数重新 O(m) 判断也是可以的。
#include<bits/stdc++.h>
using namespace std;
int n,m,Merlin;
int a[100010],tot = 0;
int ans[100010];
int max(int x,int y)
{
if(x > y)
return x;
else
return y;
}
inline void check(int x)
{
int i;
Merlin = 0;
for(i = 1;x / i >= i;i ++)
if(x % i == 0)
{
a[++tot] = i;
a[++tot] = x / i;
if(i == x / i)
tot --;
}
return;
}
int main()
{
cin >> n >> m;
for(int i = 1;i <= m;i ++)
{
int u;
cin >> u;
check(u);
}
sort(a + 1,a + tot + 1);
int j = a[1],time = 0,t = 0,i = 1;
while(i <= tot && j <= n)
{
time = 0;
while(a[i] == j && j <= n)
time ++,i ++;
ans[time] ++;
t ++;
j = a[i];
}
cout << n - t << endl;
for(int i = 1;i <= m;i ++)
{
cout << ans[i] << endl;
}
return 0;
}
T3
#include<bits/stdc++.h>
using namespace std;
const int Maxn = 1e6;
int n,x,t[Maxn + 5],line[Maxn + 5];
int check(int Merlin)
{
return max(t[line[Merlin]] + x,t[n] + Merlin);
}
int main()
{
cin >> n >> x;
for(int i = 1;i <= n;i ++)
{
cin >> t[i];
}
for(int i = n - 1;i >= 1;i --)
{
int dif;
dif = t[i + 1] - t[i];
dif ++;
for(int j = dif;j <= x && line[j] == 0;j ++)
line[j] = i;
}
t[0] = -x;
for(int i = 1;i <= x;i ++)
{
int ans = check(i);
cout << ans << endl;
}
return 0;
}
T4
#include<bits/stdc++.h>
using namespace std;
int n,a,f[60][250000],ans;
int main()
{
cin >> n;
for(int i = 1;i <= n;i ++)
{
cin >> a;
f[a][i] = i;
}
for(int i = 2;i <= 58;i ++)
{
for(int j = 1;j <= n;j ++)
{
if(!f[i][j] && f[i - 1][j])
{
f[i][j] = f[i - 1][f[i - 1][j] + 1];
}
if(f[i][j])
{
ans = i;
}
}
}
cout << ans;
return 0;
}
T5
订正时AI给的思路,我不说我是怎么做出来的
#include<bits/stdc++.h>
using namespace std;
const int maxn=100003;
stack<int> s;
queue<int> q;
int tot,tot1,tot2;
int v[maxn],v1[maxn],v2[maxn];
int nxt[maxn],nxt1[maxn],nxt2[maxn];
int first[maxn],f1[maxn],f2[maxn];
int ins[maxn],dfn[maxn],low[maxn];
int c[maxn],cnt[maxn],use[maxn];
int dis1[maxn],dis2[maxn];
int timing,col;
void add(int x,int y)
{
v[tot]=y;
nxt[tot]=first[x];
first[x]=tot++;
}
void add1(int x,int y)
{
v1[tot1]=y;
nxt1[tot1]=f1[x];
f1[x]=tot1++;
}
void add2(int x,int y)
{
v2[tot2]=y;
nxt2[tot2]=f2[x];
f2[x]=tot2++;
}
void tarjan(int x)
{
ins[x]=1;
s.push(x);
dfn[x]=low[x]=++timing;
for(int to=first[x];to!=-1;to=nxt[to])
{
if(!dfn[v[to]])
{
tarjan(v[to]);
low[x]=min(low[x],low[v[to]]);
}
else if(ins[v[to]])
low[x]=min(low[x],low[v[to]]);
}
if(dfn[x]==low[x])
{
col++;
int k;
do
{
k=s.top();
ins[k]=0;
c[k]=col;
cnt[col]++;
s.pop();
} while (k!=x);
}
}
void spfa1(int x)
{
dis1[x]=cnt[x];
q.push(x);
while(!q.empty())
{
int k=q.front();
q.pop();
for(int to=f1[k];to!=-1;to=nxt1[to])
{
if(dis1[v1[to]]<dis1[k]+cnt[v1[to]])
dis1[v1[to]]=dis1[k]+cnt[v1[to]];
if(!ins[v1[to]])
{
q.push(v1[to]);
ins[v1[to]]=1;
}
}
ins[k]=0;
}
}
void spfa2(int x)
{
dis2[x]=cnt[x];
q.push(x);
while(!q.empty())
{
int k=q.front();
q.pop();
for(int to=f2[k];to!=-1;to=nxt2[to])
{
if(dis2[v2[to]]<dis2[k]+cnt[v2[to]])
dis2[v2[to]]=dis2[k]+cnt[v2[to]];
if(!ins[v2[to]])
{
q.push(v2[to]);
ins[v2[to]]=1;
}
}
ins[k]=0;
}
}
int main()
{
int n,m,a,b,start;
cin>>n>>m;
memset(first,-1,sizeof(first));
memset(f1,-1,sizeof(f1));
memset(f2,-1,sizeof(f2));
for(int k=0;k<m;k++)
{
scanf("%d%d",&a,&b);
add(a,b);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
start=c[1];
for(int i=1;i<=n;i++)
for(int to=first[i];to!=-1;to=nxt[to])
if(c[i]!=c[v[to]])
{
add1(c[i],c[v[to]]);
add2(c[v[to]],c[i]);
}
spfa1(start);
spfa2(start);
int ans=cnt[start];
for(int i=1;i<=n;i++)
if(!use[c[i]] && dis1[c[i]])
{
use[c[i]]=1;
for(int to=f2[c[i]];to!=-1;to=nxt2[to])
{
if(!dis2[v2[to]])
continue;
ans=max(dis1[c[i]]+dis2[v2[to]]-cnt[start],ans);
}
}
cout<<ans;
return 0;
}
T6
@雪猫唤醒了我的惰性,我不说我是怎么做出来的(www.bing.com + dfs + bfs
四维偏序缩到三位偏序(核心??
bing快搜版:
#include<bits/stdc++.h>
#define fi first
#define se second
#define TIME 1e3 * clock() / CLOCKS_PER_SEC
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
inline int read() {
int x = 0;
bool f = 0;
char ch = getchar();
while(!isdigit(ch)) f |= ch == '-', ch = getchar();
while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return f ? -x : x;
}
inline void print(int x) {
if(x < 0) return putchar('-'), print(-x);
if(x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
inline int lowbit(int x) {return x & -x;}
bool Memst;
constexpr int N = 1e5 + 10;
int n;
pair<pii, pii> a[N];
pair<pii, int> b[N];
ll tree[N], dp[N];
void update(int x, ll v) {
while(x < N) {
tree[x] = max(tree[x], v);
x += lowbit(x);
}
}
ll query(int x) {
ll res = -0x3f3f3f3f3f3f3f3f;
while(x > 0) {
res = max(res, tree[x]);
x -= lowbit(x);
}
return res;
}
void solve(int l, int r) {
if(l == r) {
dp[l] += (ll)a[l].se.se;
return;
}
int mid = (l + r) >> 1;
solve(l, mid);
vector<int> v;
int tot = 0;
for(int i = l; i <= r; i++) {
int p = a[i].fi.se - a[i].fi.fi - a[i].se.fi, q = a[i].fi.se - a[i].fi.fi + a[i].se.fi;
b[++tot] = make_pair(make_pair(p, q), i);
v.push_back(q);
}
sort(b + 1, b + tot + 1);
sort(v.begin(), v.end());
v.resize(unique(v.begin(), v.end()) - v.begin());
for(int i = 1; i <= (int)v.size(); i++) tree[i] = -0x3f3f3f3f3f3f3f3f;
for(int i = 1; i <= tot; i++) {
int pos = lower_bound(v.begin(), v.end(), b[i].fi.se) - v.begin() + 1, id = b[i].se;
if(id <= mid) update(pos, dp[id]);
else dp[id] = max(dp[id], query(pos));
}
solve(mid + 1, r);
}
bool Memed;
int main(){
fprintf(stderr, "%.3lf MB\n", (&Memst - &Memed) / 1048576.0);
#ifdef JERRY_JIANG
FILE *IN = freopen("input.in", "r", stdin);
FILE *OUT = freopen("output.out", "w", stdout);
#endif
ios::sync_with_stdio(false); cin.tie(0);
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i].fi.se >> a[i].se.fi >> a[i].fi.fi >> a[i].se.se;
sort(a + 1, a + n + 1);
a[0].fi.fi = a[0].fi.se = a[0].se.fi = a[0].se.se = 0;
memset(dp, -0x3f, sizeof(dp));
dp[0] = 0;
solve(0, n);
ll ans = 0;
for(int i = 1; i <= n; i++) ans = max(ans, dp[i]);
cout << ans << endl;
fprintf(stderr, "%.3lf ms\n", TIME);
return 0;
}
自己版:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long LL;
int n,x,y,t,aaa,lshc[N],lshb[N],rt[N],lc[N*200],rc[N*200],idx;
LL k,ans,tr[N*200];
struct node
{
int a,b,c,d;
bool operator<(const node&n)const
{
if(a!=n.a)
return a<n.a;
if(b!=n.b)
return b<n.b;
return c<n.c;
}
}a[N];
void xiugai(int&o,int l,int r,int x,LL z)
{
if(!o)
o=++idx;
if(l==r)
{
tr[o]=max(tr[o],z);
return;
}
int md=l+r>>1;
if(md>=x)
xiugai(lc[o],l,md,x,z);
else
xiugai(rc[o],md+1,r,x,z);
tr[o]=max(tr[lc[o]],tr[rc[o]]);
}
LL query(int o,int l,int r,int x,int y)
{
if(!o)
return 0;
if(x<=l&&r<=y)
return tr[o];
int md=l+r>>1;
LL ans=0;
if(md>=x)
ans=max(ans,query(lc[o],l,md,x,y));
if(md<y)
ans=max(ans,query(rc[o],md+1,r,x,y));
return ans;
}
void update(int x,int y,LL z)
{
for(;x<=n;x+=x&-x)
xiugai(rt[x],1,n,y,z);
}
LL ask(int x,int y)
{
LL ans=0;
for(;x;x-=x&-x)
ans=max(ans,query(rt[x],1,n,1,y));
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&t,&x,&y,&aaa);
if(t-x-y<0||x+t-y<0)
{
--i,--n;
continue;
}
a[i]=(node){y,t-x-y,x+t-y,aaa};
lshb[i]=t-x-y;
lshc[i]=x+t-y;
}
for(int i=1;i<=n;i++)
rt[i]=++idx;
sort(a+1,a+n+1);
sort(lshb+1,lshb+n+1);
sort(lshc+1,lshc+n+1);
for(int i=1;i<=n;i++)
{
a[i].b=lower_bound(lshb+1,lshb+n+1,a[i].b)-lshb;
a[i].c=lower_bound(lshc+1,lshc+n+1,a[i].c)-lshc;
}
for(int i=1;i<=n;i++)
{
k=ask(a[i].b,a[i].c)+a[i].d;
update(a[i].b,a[i].c,k);
ans=max(ans,k);
}
printf("%lld",ans);
}
总结
难吗?
不难(doge
就是需要熟练(OK啊
总之吧,Merlin·Lee也算是考了试了,希望不要摆,希望下次周赛能漂亮点
我明知我不会赢的完美,所以我不是想输,我只是不想输的太难看,我要努力输的漂亮
开始我这个少年的奇幻漂流(@Mayday)吧:
划过挫折和彷徨,我们航行向天际线和永恒。
当诸神背过身,当百鬼夜行狂欢,当人间掀起更甚海洋的巨浪,我要竖起这属于大地的风帆。
我们将航行在耳语之间、在极端之间、在绝对之间。
繁星失语的午夜,也许没有方向,但定无风雨,也能安适静待远方天光。
Merlin·Lee
20240217
中国浙江省绍兴市诸暨市海亮中学