您的位置:首页 > 其它

20191021考试总结2

2017-10-21 20:41 253 查看

第一题:数列

题目描述:对于一个长度为n的数列,第i个数为xi。对于给定的a,b,c找到一个最小的i,使得:

a*(i+1)*x^2+(b+1)*i*x+c+i=0。

输入数据被进行了防离线加密,假设读到a,b,c真实要询问的是a+LastAns,b+LastAns,c+LastAns,对于第一组询问LastAns=0。n<=50000,最多500000组询问。

题解:当化简了N久没有任何规律后。考虑离线操作(来自出题人的误导)。当前a,b,c满足:

0=(a+Lastans) * (i+1) * x^2 + (b+LastAns+1) * i * x + c + LastAns + i = a * (i+1) * x^2+(b+1)* i * x+c+i + ((i+1) * x^2+i+x+1) * LastAns ;通过移项可推出LastAns。

分析:一直在对式子进行各种各样的化简,代换,然后什么也没有发现(。﹏。*),最后知道正解后很震惊(๑→‿ฺ←๑),思维太套路了,瞬间被题目误导,其实他加密的000结束标志就是提示,然而。。。想通了之后代码其实很好码。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=500000+10;
int t;
ll a
,b
,c
,x
,ans
;
int main(){
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
scanf("%d",&t);
for(int i=1;i<=t;i++)
scanf("%I64d",&x[i]);
int n=0;
while(~scanf("%I64d",&a[++n]))
scanf("%I64d %I64d",&b
,&c
);
int lst=ans[--n]=-a
;
for(int i=n-1;i;i--){
ll tep=a[i]*(lst+1)*x[lst]*x[lst];
tep+=(b[i]+1)*lst*x[lst]+c[i]+lst;
ll ret=((lst+1)*x[lst]*x[lst])+(lst*x[lst]+1);
lst=ans[i]=-tep/ret;
}
for(int i=2;i<=n;i++)
printf("%I64d\n",ans[i]);
}
/*
5
-2 3 1 -5 2
-5 -4 145
-1 -6 -509
-9 -14 40
-3 -13 21
-3 -3 -3
*/


第二题:刷漆

题目描述:一排栅栏有n块,其中m块前面放了一桶油漆(无限量),一个人在栅栏前随意走动,经过油漆桶时必须蘸漆,路过栅栏时栅栏被染成当前刷子的颜色,问所有栅栏都被染色共有多少情况。

题解:大水题,两个连续的油漆桶(不同颜色)长度相乘。

分析:水题水题水题水题水题水题水题水题

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000+10;
const long long mod=1e9+9;
int n,m;char str[3];
pair<int,int> col
;
int main(){
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout);
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%s",str);
col[i].second=str[0]-64;
scanf("%d",&col[i].first);
}
sort(col+1,col+m+1);
long long ans=1ll;
for(int i=2;i<=m;i++)
if(col[i].second!=col[i-1].second)
(ans*=(col[i].first-col[i-1].first))%=mod;
cout<<ans<<endl;
}


第三题:

题目描述:一群妹子,站在数轴上(编号从大到小),给出一些限制,(两个人之间距离最小或最大为多少),求1到n最大距离。

题解:差分约束系统。

分析: spfa()负权环判错了/(ㄒoㄒ)/~~。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N=1000+10;
const int M=100000+10;
const int inf=0x3f3f3f3f;
inline void getint(int&num){
char c;int flag=1;num=0;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
num*=flag;
}
int n,ml,dl,u,v,c,cnt,dis
,que
;
int fir
,tar[M],nxt[M],w[M];
bool in
;
queue<int> q;
inline void link(int a,int b,int c){
tar[++cnt]=b,w[cnt]=c;
nxt[cnt]=fir[a],fir[a]=cnt;
}
int spfa(int st,int ed){
memset(in,0,sizeof in);
memset(que,0,sizeof que);
memset(dis,0x3f,sizeof dis);
int inque=1;que[st]=1;
dis[st]=0,q.push(st);
while(!q.empty()){
int t=q.front();q.pop();
in[t]=0,inque++;
if(inque>=5*n) return -1;
for(int i=fir[t];i;i=nxt[i])
if(dis[tar[i]]>dis[t]+w[i]){
dis[tar[i]]=dis[t]+w[i];
if(!in[tar[i]]){
in[tar[i]]=1,que[tar[i]]++;
q.push(tar[i]);
if(que[tar[i]]>n)
return -1;
}
}
}
if(dis[ed]==inf) return -2;
return dis[ed];
}
int main(){
freopen("layout.in","r",stdin);
freopen("layout.out","w",stdout);
getint(n),getint(ml),getint(dl);
while(ml--){
getint(u),getint(v),getint(c);
link(v,u,c);
}
while(dl--){
getint(u),getint(v),getint(c);
link(u,v,-c);
}
for(int i=1;i<n;i++) link(i,i+1,0);
printf("%d\n",spfa(n,1));
}
/*
4 2 1
1 3 10
2 4 20
2 3 3
*/


总结:第三题不应该丢分(才整理的模板居然忘了)模板不熟啊啊啊啊啊啊啊啊。。。第一题思维还不够发散,被限制在了常规思维里。(但最后时间没有把握好,暴力都来不及了/(ㄒoㄒ)/~~),这一场发挥得很不好,下一场要更好的计算时间。。。对于想不出的题目要注意转换思维,不要受题目描述误导,认真观察题目中的暗示隐藏信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: