Day1

T1.小学奥数。。。

代码:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
long long a,b;
int main()
{
scanf("%lld%lld",&a,&b);
long long ans=a*b-a-b;
printf("%lld",ans);
return 0;
}

 T2:大模拟题,没什么好讲的(我还写的特别麻烦,估计最傻逼的代码)

代码:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define INF 1000
using namespace std;
int T,l;
bool vis[1005],vis1[10005];
char s[10005],ch[105][10];
bool c[10005],e[1005];
int d[1005];
char ssss[1005],sss[10005],ss[105];
int a[1005],b[1005];
int main()
{
scanf("%d",&T);
while (T--){
bool flag=true;
int sum=0; bool zong=true;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%d%s",&l,s+1);
int n=strlen(s+1);
if (s[3]=='n') flag=true;
else flag=false;
if (flag){
int ckr=0;
for (int i=1;i<=n;i++){
if (s[i]=='^'){
ckr=i;
break;
}
}
for (int i=ckr+1;i<=n;i++){
if (s[i]>='0'&&s[i]<='9') sum=sum*10+s[i]-'0';
else break;
}
}
else {
int ckr=0;
for (int i=1;i<=n;i++){
if (s[i]=='('){
ckr=i;
break;
}
}
for (int i=ckr+1;i<=n;i++){
if (s[i]>='0'&&s[i]<='9') sum=sum*10+s[i]-'0';
else break;
}
}
if (!flag) sum=0;
for (int i=1;i<=l;i++){
scanf("%s",ss);
if (ss[0]=='F'){
cin>>ch[i][0];
//scanf("%s",ch[i][0]);
scanf("%s%s",sss+1,ssss+1);
if (sss[1]=='n') a[i]=INF;
else {
int n=strlen(sss+1);
for (int j=1;j<=n;j++) a[i]=a[i]*10+sss[j]-'0';
}
if (ssss[1]=='n') b[i]=INF;
else {
int n=strlen(ssss+1);
for (int j=1;j<=n;j++) b[i]=b[i]*10+(ssss[j]-'0');
}
if (a[i]==INF&&b[i]==INF) d[i]=0;
else if (a[i]>b[i]) d[i]=-1;
else if (a[i]==INF&&b[i]<INF) d[i]=-1;
else if (a[i]<INF&&b[i]<INF) d[i]=0;
else if (a[i]<INF&&b[i]==INF) d[i]=1;
c[i]=true;
}
else c[i]=false;
}
memset(vis,false,sizeof(vis));
memset(vis1,false,sizeof(vis1));
int i=1; int j=1; int tot=0; int bianlitot=0;
int Max1=0;
int flag1=0;
while (j<=l){
if (c[j]==true){
if (vis[ch[j][0]-'a']){
if (zong) puts("ERR");
zong=false;
}
vis[ch[j][0]-'a']=true;
if (flag1==0){
if (d[j]==1) tot++,e[j]=true;
else if (d[j]==0) tot=tot,e[j]=true;
else if (d[j]==-1) flag1++,e[j]=false;
}
else{
tot=tot;
e[j]=false;
if (d[j]==-1) flag1++;
}
bianlitot++;
Max1=max(Max1,tot);
}
else {
bianlitot--;
if (bianlitot<0){
if (zong) puts("ERR");
zong=false;
}
for (int k=j;k>=1;k--){
if (c[k]==true&&vis1[k]==false){
vis[ch[k][0]-'a']=false;
vis1[k]=true;
if (e[k]) tot=tot-d[k];
else if (e[k]==false){
tot=tot;
if (d[k]==-1) flag1--;
}
break;
}
}
Max1=max(Max1,tot);
}
j++;
}
if (!zong) continue;
if (bianlitot!=0) puts("ERR");
else{
if (Max1==sum) puts("Yes");
else puts("No");
}
}
return 0;
}

T3.一看k<=50,很显然的状态就有了

我们考虑用dp[i][j]表示到i这个点浪费了的代价为j,这里浪费的代价可以这么理解:就是到i相比于最短路dis[i]来说长了j,也就是说走了dis[i]+j的路

考虑转移dp[i][j]->dp[v][j+dis[i]+e[i].step-dis[v]](当前走得路径+到v的长度和到v的最短路进行比较,就知道了浪费了多少),其中dis[i]表示到i的最短路

注意更新顺序,关于dis排序来更新

另外DP的时候要先枚举差量,一定是差量小的来更新差量大的

这样就有70分了

我们考虑怎么拿满分。

注意到一个套路,就是如果拓扑排序后有点剩余,那么剩下的点一定构成环

然后对于-1的情况就是有一个0环在路径上

我们用拓扑排序判一下就行了

同一个 0 环上任意一个点到1的最短路和到n的最短路都一样

所以当这个点 i 满足 dis1[i]+disn[i]<=dis1[n]+K 时,就可以输出 -1了

代码:

#include<bits/stdc++.h>
#define N 200005
#define M 100005
using namespace std;
int T,n,m,K,Mod,kk,kkk,kkkk,x,y,z;
int head[M],head1[M],Head[N],dis1[M],dis2[N],ru[M],dp[M][55],tmp[M],q[N*100];
struct Edge{int nxt,to,step;}e[N];
struct Edge1{int nxt,to,step;}e1[N];
struct Edge2{int nxt,to;}E[N];
inline void link(int x,int y,int z){e[++kk].nxt=head[x];e[kk].to=y;e[kk].step=z;head[x]=kk;}
inline void link1(int x,int y,int z){e1[++kkk].nxt=head1[x];e1[kkk].to=y;e1[kkk].step=z;head1[x]=kkk;}
inline void Link(int x,int y){E[++kkkk].nxt=Head[x];E[kkkk].to=y;Head[x]=kkkk;}
inline void spfa1(){
memset(dis1,127,sizeof(dis1));dis1[1]=0;
int left1=1;int right1=1;q[1]=1;
while (left1<=right1){
int u=q[left1++];
for (int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if (dis1[v]>dis1[u]+e[i].step){
dis1[v]=dis1[u]+e[i].step;
q[++right1]=v;
}
}
}
}
inline void spfa2(){
memset(dis2,127,sizeof(dis2));dis2[n]=0;
int left1=1;int right1=1;q[1]=n;
while (left1<=right1){
int u=q[left1++];
for (int i=head1[u];i;i=e1[i].nxt){
int v=e1[i].to;
if (dis2[v]>dis2[u]+e1[i].step){
dis2[v]=dis2[u]+e1[i].step;
q[++right1]=v;
}
}
}
}
int id[N];
inline bool cmp(int x,int y){if(dis1[x]==dis1[y])return id[x]<id[y];else return dis1[x]<dis1[y];}
inline void solve(){
memset(dp,0,sizeof(dp));dp[1][0]=1;
for (int i=1;i<=n;i++) tmp[i]=i;
sort(tmp+1,tmp+n+1,cmp);
for (int k=0;k<=K;k++){//注意先枚举差量,一定是差量小的先更新差量大的
for (int i=1;i<=n;i++){
int u=tmp[i];
for (int j=head[u];j;j=e[j].nxt){
int v=e[j].to;
if (k+dis1[u]+e[j].step-dis1[v]>K) continue;
dp[v][k+(dis1[u]+e[j].step-dis1[v])]=1ll*(dp[v][k+(dis1[u]+e[j].step-dis1[v])]+dp[u][k])%Mod;
}
}
}
int ans=0;
for (int i=0;i<=K;i++) ans=(ans+dp[n][i])%Mod;
if (!ans) puts("-1");else printf("%d\n",ans);
}
bool check(){//拓扑排序找环,如果存在一个环,那么这个环中的点都不会加入到拓扑序中,显然不可能会入度为0
int left1=1;int right1=0;//right1=0打成right1=1了
for (int i=1;i<=n;i++) if (!ru[i]) q[++right1]=i,id[i]=n;
while (left1<=right1){
int u=q[left1++];
for (int i=Head[u];i;i=E[i].nxt){
int v=E[i].to;
if (!--ru[v]) q[++right1]=v;
}
}
for (int i=1;i<=right1;i++) id[q[i]]=i;
for (int i=1;i<=n;i++)
if (ru[i]&&dis1[i]+dis2[i]<=dis1[n]+K) return true;//如果i这个环在可能的路上那么就gg
return false;
}
inline void init(){
memset(Head,0,sizeof(Head));kkkk=0;
memset(head,0,sizeof(head));kk=0;
memset(head1,0,sizeof(head1));kkk=0;
memset(ru,0,sizeof(ru));
}
int main(){
scanf("%d",&T);
while (T--){
init();
scanf("%d%d%d%d",&n,&m,&K,&Mod);
for (int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
link(x,y,z);link1(y,x,z);
if (!z) Link(x,y),ru[y]++;
}
spfa1();spfa2();
if (check()) puts("-1");
else solve();
}
return 0;
}
/*1
2 2 6 5
1 2 2
2 1 2*/

  

NOIP2017Day1题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. 内存分配的原理__进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)

    如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor faul ...

  2. 认识 SurfaceView

    SurfaceView是基于View视图进行扩展的视图类,适用于2D游戏开发,主要特点有: [1]surfaceView中对于画布的重绘是由一个新的线程去绘制,因此可以处理一些耗时的操作 [2]sur ...

  3. C语言实现ifconfig获取网卡接收和发送流量统计

    在Windows下我们可以利用ipconfig命令获取网卡的相关信息,在Linux下命令是ifconfig 我们可以获取的信息更为丰富,其中包括网卡接收和发送的流量,用C语言实现这个命令并不是一件简单 ...

  4. Android开发你不知道的TIPS

    1.Space space是Android 4.0中新增的一个控件,它实际上可以用来分隔不同的控件,其中形成一个空白的区域.这是一个轻量级的视图组件,它可以跳过Draw,对于需要占位符的任何场景来说都 ...

  5. OS X升级到10.11后Xcode6.4界面无iOS device选择栏的解决办法

    原来在Xcode6.4项目运行按钮右侧会有一个可以选择设备或模拟器的选择栏,但是升级后没有了.但是Xcode7.0.1打开同样的项目会有显示. 简单找了一下无果后,发现咋Xcode顶部菜单里可以找到切 ...

  6. Unity C# 自定义TCP传输协议以及封包拆包、解决粘包问题

    本文只是初步实现了一个简单的TCP自定协议,更为复杂的协议可以根据这种方式去扩展. TCP协议,通俗一点的讲,它是一种基于socket传输的由发送方和接收方事先协商好的一种消息包组成结构,主要由消息头 ...

  7. Linux - 简单好用的计算器 bc

    如果在文本模式当中,突然想要作一些简单的加减乘除,偏偏手边又没有计算器!这个时候要笔算吗? Linux有提供一支计算程序,那就是bc.你在命令列输入bc后,屏幕会显示出版本信息, 之后就进入到等待指示 ...

  8. 传统定时器技术 Timer and TimerTask

    本文为张孝祥java并发课程的学习笔记. java.util.Timer定时器,实际上是个线程,定时调度所拥有的TimerTasks. 一个TimerTask实际上就是一个拥有run方法的类,需要定时 ...

  9. C语言之多线程机制(程序可以同时被执行而不会相互干扰)

    接触过linux的人或多或少知道,linux有多线程的机制,也就是说程序可以同时执行,不受干扰,关于这个在我以前的博文里有过类似模拟的时间片轮转程序,跟这个其实是类似的.其实在window上,线程的头 ...

  10. 为什么我们要使用ssh框架技术,及感想

    前言: 在公司从C++转向Java Web方向大概有3个月(11月初-1月底)了.三个月前对Java和Web还几乎是零基础.然后从安装Eclipse,MySQL,tomcat开始,到学习HTML/CS ...