Problem 1 机器人(robot.cpp/c/pas)

【题目描述】

早苗入手了最新的Gundam模型。最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧。

早苗的新模型可以按照输入的命令进行移动,命令包括‘E’、‘S’、‘W’、‘N’四种,分别对应东南西北。执行某个命令时,它会向对应方向移动一个单位。作为新型机器人,它可以执行命令串。对于输入的命令串,每一秒它会按命令行动一次。执行完命令串的最后一个命令后,会自动从头开始循环。在0时刻时机器人位于(0,0)。求T秒后机器人所在位置坐标。

【输入格式】

第1行:一个字符串,表示早苗输入的命令串,保证至少有1个命令

第2行:一个正整数T

【输出格式】

2个整数,表示T秒时,机器人的坐标。

【样例输入】

NSWWNSNEEWN

12

【样例输出】

-1 3

【数据范围】

对于60%的数据 T<=500,000 且命令串长度<=5,000

对于100%的数据 T<=2,000,000,000 且命令串长度<=5,000

【注意】

向东移动,坐标改变改变为(X+1,Y);

向南移动,坐标改变改变为(X,Y-1);

向西移动,坐标改变改变为(X-1,Y);

向北移动,坐标改变改变为(X,Y+1);

Problem 2 数列(seq.cpp/c/pas)

【题目描述】

a[1]=a[2]=a[3]=1

a[x]=a[x-3]+a[x-1]  (x>3)

求a数列的第n项对1000000007(10^9+7)取余的值。

【输入格式】

第一行一个整数T,表示询问个数。

以下T行,每行一个正整数n。

【输出格式】

每行输出一个非负整数表示答案。

【样例输入】

3

6

8

10

【样例输出】

4

9

19

【数据范围】

对于30%的数据 n<=100;

对于60%的数据 n<=2*10^7;

对于100%的数据 T<=100,n<=2*10^9;

Problem 3 虫洞(holes.cpp/c/pas)

【题目描述】

N个虫洞,M条单向跃迁路径。从一个虫洞沿跃迁路径到另一个虫洞需要消耗一定量的燃料和1单位时间。虫洞有白洞和黑洞之分。设一条跃迁路径两端的虫洞质量差为delta。

1.从白洞跃迁到黑洞,消耗的燃料值减少delta,若该条路径消耗的燃料值变为负数的话,取为0。

2.从黑洞跃迁到白洞,消耗的燃料值增加delta。

3.路径两端均为黑洞或白洞,消耗的燃料值不变化。

作为压轴题,自然不会是如此简单的最短路问题,所以每过1单位时间黑洞变为白洞,白洞变为黑洞。在飞行过程中,可以选择在一个虫洞停留1个单位时间,如果当前为白洞,则不消耗燃料,否则消耗s[i]的燃料。现在请你求出从虫洞1到N最少的燃料消耗,保证一定存在1到N的路线。

【输入格式】

第1行:2个正整数N,M

第2行:N个整数,第i个为0表示虫洞i开始时为白洞,1表示黑洞。

第3行:N个整数,第i个数表示虫洞i的质量w[i]。

第4行:N个整数,第i个数表示在虫洞i停留消耗的燃料s[i]。

第5..M+4行:每行3个整数,u,v,k,表示在没有影响的情况下,从虫洞u到虫洞v需要消耗燃料k。

【输出格式】

一个整数,表示最少的燃料消耗。

【样例输入】

4 5

1 0 1 0

10 10 100 10

5 20 15 10

1 2 30

2 3 40

1 3 20

1 4 200

3 4 200

【样例输出】

130

【数据范围】

对于30%的数据: 1<=N<=100,1<=M<=500

对于60%的数据: 1<=N<=1000,1<=M<=5000

对于100%的数据: 1<=N<=5000,1<=M<=30000

其中20%的数据为1<=N<=3000的链

1<=u,v<=N, 1<=k,w[i],s[i]<=200

【样例说明】

按照1->3->4的路线。


T1:

直接模拟即可

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MAXN 5000
using namespace std;
int dx,dy;
int gx[]={,,-,};
int gy[]={,-,,};
//E S W N
int x,y;
int T;
char s[MAXN]; int main()
{
scanf("%s",s+);
scanf("%d",&T);
int len=strlen(s+);
for(int i=;i<=len;i++){
if('E'==s[i]){
dx+=gx[];
dy+=gy[];
}
else if('S'==s[i]){
dx+=gx[];
dy+=gy[];
}
else if('W'==s[i]){
dx+=gx[];
dy+=gy[];
}
else{
dx+=gx[];
dy+=gy[];
}
}
int q=T/len;
int p=T%len;
x+=(dx*q),y+=(dy*q);
if(p){
for(int i=;i<=p;i++){
if('E'==s[i]){
x+=gx[];
y+=gy[];
}
else if('S'==s[i]){
x+=gx[];
y+=gy[];
}
else if('W'==s[i]){
x+=gx[];
y+=gy[];
}
else{
x+=gx[];
y+=gy[];
}
}
}
printf("%d %d\n",x,y);
return ;
}

Code1

T2:

用矩阵快速幂优化,得公式

f x        1 0 1                 f 3

(f x-1)=(1 0 0) ^ (x-3) *  (f 2)

f x-2     0 1 0                 f 1

时间复杂度O(T*logn)

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MOD 1000000007
#define ll long long
using namespace std;
struct Mat{
ll s[][];
Mat(){
memset(s,,sizeof(s));
}
friend Mat operator * (const Mat &A,const Mat &B){
Mat ret;
for(int i=;i<;i++){
for(int j=;j<;j++){
for(int k=;k<;k++){
ret.s[i][j]=(ret.s[i][j]+(A.s[i][k]*B.s[k][j])%MOD)%MOD;
}
}
}
return ret;
}
Mat operator = (const Mat &A){
for(int i=;i<;i++){
for(int j=;j<;j++){
s[i][j]=A.s[i][j];
}
}
}
};
int T;
Mat Power(Mat A,int p){
if(==p){
return A;
}
if(p&){
return Power(A*A,p>>)*A;
}
else{
return Power(A*A,p>>);
}
}
int main()
{
// freopen("data.in","r",stdin);
Mat A;
A.s[][]=,A.s[][]=,A.s[][]=;
A.s[][]=,A.s[][]=,A.s[][]=;
A.s[][]=,A.s[][]=,A.s[][]=;
scanf("%d",&T);
for(int i=;i<=T;i++){
int n;
scanf("%d",&n);
if(==n||==n||==n){
printf("1\n");
continue;
}
Mat t=Power(A,n-);
ll ans=(t.s[][]+t.s[][])%MOD;
ans=(ans+t.s[][])%MOD;
printf("%lld\n",ans);
}
return ;
}

Code2

T3:

这题就是个最短路,稍微修改下即可

我第一次用dijk写的,结果T了6个点

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
#define MAXN 5005
#define MAXM 30005
#define INF 0x7f7f7f7f
using namespace std;
struct Node{
int s,u;
int d;
Node(int ss,int uu,int dd){
s=ss,u=uu,d=dd;
}
Node(){
s=u=;
d=INF;
}
friend bool operator < (const Node &p1,const Node &p2){
return (p1.d<p2.d);
}
friend bool operator > (const Node &p1,const Node &p2){
return !(p1.d<p2.d);
}
};
priority_queue<Node> q;
int d[][MAXN];
int V,E;
int s[MAXN];
int w[MAXN];
int first[MAXN],Next[MAXM],to[MAXM],W[MAXM],cnt;
int p[][MAXN];
// 0 not change 1 change
int Abs(int x){
return (x>)?x:-x;
}
void Add(int x,int y,int w){
Next[++cnt]=first[x]; first[x]=cnt; to[cnt]=y; W[cnt]=w;
//single edge
}
void dijk(){
d[][]=;
q.push(Node(,,));
while(!q.empty()){
Node t=q.top(); q.pop();
// now using t.s
int ds=(!t.s);
int x=t.u;
if(d[t.s][t.u]!=t.d){
continue;
}
//stay
if(!p[t.s][x]){
if(d[ds][x]>d[t.s][x]){
d[ds][x]=d[t.s][x];
q.push(Node(ds,x,d[ds][x]));
}
}
else{
if(d[ds][x]>d[t.s][x]+s[x]){
d[ds][x]=d[t.s][x]+s[x];
q.push(Node(ds,x,d[ds][x]));
}
}
for(int e=first[x];e;e=Next[e]){
int y=to[e];
int dw=W[e];
if(p[t.s][x]!=p[t.s][y]){
//0 white 1 black
//0->1 w-=delta w=max(w,0)
//1->0 w+=delta
if(!p[t.s][x]){
dw-=Abs(w[x]-w[y]);
dw=max(dw,);
}
else{
dw+=Abs(w[x]-w[y]);
}
}
if(d[ds][y]>d[t.s][x]+dw){
d[ds][y]=d[t.s][x]+dw;
q.push(Node(ds,y,d[ds][y]));
}
}
}
}
int main()
{
// freopen("data.in","r",stdin);
memset(d,0x7f,sizeof(d));
scanf("%d%d",&V,&E);
for(int i=;i<=V;i++){
scanf("%d",&p[][i]);
p[][i]=(!p[][i]);
}
for(int i=;i<=V;i++){
scanf("%d",&w[i]);
}
for(int i=;i<=V;i++){
scanf("%d",&s[i]);
}
for(int i=;i<=E;i++){
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
Add(x,y,k);
}
dijk();
int ans=min(d[][V],d[][V]);
printf("%d\n",ans);
return ;
}

Code3

后来改用SPFA,AC了

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
#define MAXN 5005
#define MAXM 30005
#define INF 0x7f7f7f7f
using namespace std;
struct Node{
int s,u;
int d;
Node(int ss,int uu,int dd){
s=ss,u=uu,d=dd;
}
Node(){
s=u=;
d=INF;
}
};
int d[][MAXN];
bool b[][MAXN];
queue<Node> q;
int V,E;
int s[MAXN];
int w[MAXN];
int first[MAXN],Next[MAXM],to[MAXM],W[MAXM],cnt;
int p[][MAXN];
// 0 not change 1 change
int Abs(int x){
return (x>)?x:-x;
}
void Add(int x,int y,int w){
Next[++cnt]=first[x]; first[x]=cnt; to[cnt]=y; W[cnt]=w;
//single edge
}
void SPFA(){
d[][]=;
b[][]=;
q.push(Node(,,));
while(!q.empty()){
Node t=q.front(); q.pop();
int S=t.s;
int ds=(!S);
int x=t.u;
b[S][x]=;
// now using t.s
//stay
if(!p[S][x]){
if(d[ds][x]>d[S][x]){
d[ds][x]=d[S][x];
if(!b[ds][x]){
b[ds][x]=;
q.push(Node(ds,x,d[ds][x]));
}
}
}
else{
if(d[ds][x]>d[S][x]+s[x]){
d[ds][x]=d[S][x]+s[x];
if(!b[ds][x]){
b[ds][x]=;
q.push(Node(ds,x,d[ds][x]));
}
}
}
for(int e=first[x];e;e=Next[e]){
int y=to[e];
int dw=W[e];
if(p[S][x]!=p[S][y]){
//0 white 1 black
//0->1 w-=delta w=max(w,0)
//1->0 w+=delta
if(!p[S][x]){
dw-=Abs(w[x]-w[y]);
dw=max(dw,);
}
else{
dw+=Abs(w[x]-w[y]);
}
}
if(d[ds][y]>d[S][x]+dw){
d[ds][y]=d[S][x]+dw;
if(!b[ds][y]){
b[ds][y]=;
q.push(Node(ds,y,d[ds][y]));
}
}
}
}
}
int main()
{
// freopen("data.in","r",stdin);
memset(d,0x7f,sizeof(d));
scanf("%d%d",&V,&E);
for(int i=;i<=V;i++){
scanf("%d",&p[][i]);
p[][i]=(!p[][i]);
}
for(int i=;i<=V;i++){
scanf("%d",&w[i]);
}
for(int i=;i<=V;i++){
scanf("%d",&s[i]);
}
for(int i=;i<=E;i++){
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
Add(x,y,k);
}
SPFA();
int ans=min(d[][V],d[][V]);
printf("%d\n",ans);
return ;
}

Code4

可见SPFA效率比dijk高很多啊。。。

最新文章

  1. js返回顶部效果
  2. 如何使用新浪微博账户进行应用登录验证(基于Windows Azure Mobile Service 集成登录验证)
  3. Hadoop学习笔记(一)
  4. paper 87:行人检测资源(下)代码数据【转载,以后使用】
  5. 数组的join()函数操作
  6. 《C和指针》 读书笔记 -- 第10章 结构和联合
  7. css案例学习之用thead、tbody、tfoot实现漂亮的table布局
  8. BZOJ 1208: [HNOI2004]宠物收养所(BST)
  9. 【转】在PC上测试移动端网站和模拟手机浏览器的5大方法
  10. windows全系列激活脚本-改良版.cmd
  11. shell脚本学习(四)
  12. iOS_init相关信息
  13. 【BZOJ2132】圈地计划(最小割)
  14. ElasticSearch head 插件安装
  15. ASP.NET MVC 执行流程介绍
  16. JsonRequestBehavior不存在问题,JsonRequestBehavior属于哪个dll
  17. CP IPS功能测试
  18. 19款Windows实用软件推荐,满满的干货,总有一款是你必备的
  19. 使用UWA GOT优化Unity性能和内存
  20. 使用js在HTML中自定义字符串格式化方法

热门文章

  1. iOS 简易无限滚动的图片轮播器-SDCycleScrollView
  2. 【深度学习】深入理解ReLU(Rectifie Linear Units)激活函数
  3. 微信小程序组件学习中
  4. 单点登录实现机制:web-sso
  5. 分布式服务框架HSF
  6. 【52ABP实战教程】0.3-- 从github推送代码回vsts实现双向同步
  7. 十个你需要在 PHP 7 中避免的坑
  8. leetcode算法: Find Largest Value in Each Tree Row
  9. 最小二乘法多项式拟合的Java实现
  10. Struts(十七):通过CURD来学习paramsPrepareParams拦截器栈