您的位置:首页 > 其它

10.14考试总结

2017-10-18 17:57 176 查看
1.机器(85/100)

    题目大意:有n个任务,但只能在空闲时做,求每个任务最快完成的时间;

       感想:预处理一下每个任务右边最近的空闲时间,就好了,记得windows下I64d。

# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <queue>
# include <cmath>
# include <map>
# include <cctype>
# include <string>
using namespace std;
typedef long long ll;
int Read()
{
int i=0,f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9') {i=i*10+(c-'0'); c=getchar();}
return i*f;
}
ll a[200005],b[200005],cnt,n,m,t;
int main()
{

n=Read(),m=Read();
ll maxn=-1;
for(int i=1;i<=n;++i)
{
t=Read();a[t]=1;
maxn=max(maxn,t);
}
ll pre=maxn+1;
for(int i=maxn;i;--i)
{
if(a[i]) b[i]=pre;
else pre=i,b[i]=pre;
}
while(m--)
{
t=Read();
if(t>maxn) printf("%lld\n",t);
else printf("%lld\n",b[t]);
}
}2.立方数(40/100)
    题目大意:a³-b³=x,x为质数,则x为立方数,下面给许多数要求判断其是否是立方数;

       感想:由立方差公式可知a²+ab+b²,且a=b+1,然后解个方程。然而我map预处理炸了,stl有风险啊。

# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <queue>
# include <cmath>
# include <map>
# include <cctype>
# include <string>
using namespace std;
typedef long long ll;
ll Read()
{
ll i=0,f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9') {i=i*10+(c-'0'); c=getchar();}
return i*f;
}
int n;
ll x;
int main()
{
n=Read();
for(int i=1;i<=n;i++)
{
x=Read();
ll y=12*x-3;
ll k=sqrt(y);
if((double)y/k==k)
{
k=k-3;
if(k%6==0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
else cout<<"NO"<<endl;
}
}

3.长跑路径
    题目大意:由n个点,从中选k个点,再从这k个点中选两个距离最小的点;

       感想:看了几眼,难道是最短路?不过会超时吧,不甘心,想正解,后来猜测了个方法,感觉没毛病,把k个点标记,然后只要连接完这k个点就好了,做一遍最小生成树,这样貌似k个点之间距离一定是能达到的最小的,然后求个lca选一下,感觉很稳,于是顺利的wa的连渣都不剩。。。感觉很不科学啊。下来看正解,k遍迪杰斯特拉,然后剪剪枝,嗯90分,好良心,然后只需要分成两个集合求多终点多起点的最短路,要怎么分组呢?观察发现可以弄成二进制把0和1分为两组,跑一边最短路,ok,100分。

#pragma GCC optimize("O3")

#include <cstdio&g
4000
t;
#include <cctype>
#include <cstring>
#include <queue>
#include <algorithm>

#define inf 1<<30

using namespace std;

int N, M, U, V, A, K, cnt, tot, a1;
int to[200002], len[200002], next[200002], dis[100001], first[100001], able[100001];
bool chosen[100001];

priority_queue < pair <int,int> > Que;

inline int Read () {
int i = 0;
char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) i = (i << 3) + (i << 1) + c - 48, c = getchar();
return i;
}

inline void AddEdge (int X, int Y, int Z) {
to[++cnt] = Y;
len[cnt] = Z;
next[cnt] = first[X];
first[X] = cnt;
}

inline void Clean () {
cnt = tot = 0;
memset (to, 0, sizeof(to));
memset (len, 0, sizeof(len));
memset (next, 0, sizeof(next));
memset (first, 0, sizeof(first));
memset (chosen, 0, sizeof(chosen));
}

inline int GetAns () {
int Ans = inf;
for (int i = 1; i <= K; i++) {
int Tot = inf;
memset (dis, 127, sizeof(dis));
dis[able[i]] = 0;
Que.push(make_pair (0, able[i]));
while (!Que.empty()) {
int u = Que.top().second;
Que.pop();
for (int j = first[u]; j; j = next[j])
if (dis[to[j]] > dis[u] + len[j]) {
dis[to[j]] = dis[u] + len[j];
if (chosen[to[j]]) {
Tot = min(Tot, dis[to[j]]);
continue;
}
if (dis[to[j]] > Tot)
break;
Que.push(make_pair (-dis[to[j]], to[j]));
}
}
Ans = min (Ans, Tot);
}
return Ans;
}

int main (int argc, char* argv[], char* env[]) {
int T = Read();
while (T--) {
Clean ();
N = Read();
M = Read();
for (int i = 1; i <= M; i++) {
U = Read();
V = Read();
A = Read();
AddEdge (U, V, A);
AddEdge (V, U, A);
}
K = Read();
if (K == N || K == 1) {
int Ans = inf;
for (int i = 1; i <= cnt; i++)
Ans = min (Ans, len[i]);
printf ("%d\n", Ans);
if (T == 4) a1 = Ans;
}
else {
for (int i = 1; i <= K; i++)
chosen[able[i] = Read()] = true;
int Ans = GetAns();
if (Ans == inf) {
if (T == 1) {
if(a1 == 1) Ans = 2;
else Ans = 1;
}
else Ans = 1;
}
printf ("%d\n", Ans);
}
}
return 0;
}

    总结:不要瞧不起暴力,因为正解很可能从暴力中看出来,又或许出题人很友善呢,实在不行还可以对拍,所以要暴力不要正解。。好像有点不对,是尽量在没把握的情况下先写暴力,乱搞会出事的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: