NOIP 2017 Day1 题解?
2017-12-06 09:25
281 查看
NOIP 2017 Day1 我的程序(AC)
题目详解
T1
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<vector> #include<queue> #include<cmath> #define LL long long using namespace std ; int main() { freopen("math.in","r",stdin); freopen("math.out","w",stdout); LL a,b; scanf("%lld%lld",&a,&b); if (!(a&1)) swap(a,b); LL tmp1=a-1; LL tmp2=a-2; LL tmp3=(a-2)+(a-1)*(b-2); printf("%lld\n",tmp3); return 0; }
上面的tmp3我是用找规律(数列)弄出来的,考试的时候脑子抽了,居然没化简,但是对拍了没错我也不虚,就这样交了。
其实就是积减和公式A×B−A−B就是答案。
T2
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<vector> using namespace std ; const int N=2333; const int M=27; int val ,used[M]; int T,goal=0,noin=0,top=1,n,ans,nowans; bool ERR=0; string st; void init() { cin>>n; cin>>st; //cerr<<n<<' '<<st<<' '; int len=st.size(); if (st[2]=='n') for(int i=4;i<=len-1;i++) if (st[i]>='0'&&st[i]<='9') goal=goal*10+st[i]-'0'; else break; //cerr<<"goal="<<goal<<endl; } void F() { char x; string y,z; cin>>x>>y>>z; //cerr<<x<<' '<<y<<' '<<z<<endl; int id=x-'a',u=0,v=0; int lenu=y.size(),lenv=z.size(); if (used[id]||ERR) { ERR=1; //cerr<<"ERR?"<<endl; return ; } used[id]=top; //cerr<<"id="<<id<<endl; if (y=="n") u=2333; else for (int i=0;i<=lenu-1;i++) u=u*10+y[i]-'0'; if (z=="n") v=2333; else for (int i=0;i<=lenv-1;i++) v=v*10+z[i]-'0'; //cerr<<u<<' '<<v<<endl; if (u>v||noin) noin++,val[top]=0; else if (v-u>=1000) val[top]=1; else val[top]=0; nowans+=val[top]; ans=max(ans,nowans); top++; } void E() { top--; if (top<1||ERR) { ERR=1; return ; } for (int i=0;i<=26;i++) if (used[i]==top) used[i]=0; if (noin) noin--; nowans-=val[top]; ans=max(ans,nowans); } bool check() { //cerr<<"ans="<<ans<<endl; if (ans!=goal) return 0; return 1; } void reset() { goal=ERR=ans=nowans=noin=0; top=1; memset(used,0,sizeof used); memset(val,0,sizeof val); } void solve() { for(int i=1;i<=n;i++) { cin>>st; //cerr<<st<<endl; if (st=="F") F(); else if (st=="E") E(); } if (ERR||top!=1) printf("ERR\n"); else if (check()) printf("Yes\n"); else printf("No\n"); } int main() { // freopen("1.in","r",stdin); cin>>T; while (T--) { reset(); init(); solve(); } return 0; }
这题是纯模拟题,但是为了提高准确率,我比较推荐用模块化的写法。用栈维护循环自然不用说,需要注意的就是每次都要清空。因为题目说了N是个远大于100的数,其实可以把N转化成具体数字,统一操作的话似乎容易做很多,可以更清晰思路,模块化的好处就体现在这里了。
T3
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<vector> using namespace std ; const int N=100100; const int M=200200; const int K=55; bool flag=0; int cnt,n,m,k,mod,ans,T; int f [K],go [K],vis ,head ,dis ; queue<int>q; struct edge { int v,w,nxt; }e[M]; void add(int u,int v,int w) { cnt++; e[cnt].v=v; e[cnt].w=w; e[cnt].nxt=head[u]; head[u]=cnt; } void init() { scanf("%d%d%d%d",&n,&m,&k,&mod); for (int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(v,u,w); } } void spfa(int s,int t) { dis[s]=0; vis[s]=1; q.push(s); while (!q.empty()) { int u=q.front(); q.pop(); for (int i=head[u];i;i=e[i].nxt) { int v=e[i].v,w=e[i].w; if (dis[u]+w<dis[v]||dis[v]==-1) { dis[v]=dis[u]+w; if (!vis[v]) { vis[v]=1; q.push(v); } } } vis[u]=0; } } int dfs(int u,int k) { if (go[u][k]) { flag=1; return 0; } if (f[u][k]!=-1) return f[u][k]; go[u][k]=1; int re=0; for (int i=head[u];i;i=e[i].nxt) { int v=e[i].v,w=e[i].w,tmp; tmp=k-(dis[u]+w-dis[v]); if (tmp<0||tmp>k) continue ; re=(re+dfs(v,tmp))%mod; if (flag) { go[u][k]=0; return 0; } } go[u][k]=0; if (u==1&&k==0) re++; return f[u][k]=re; } void solve() { spfa(n,1); for (int i=0;i<=k;i++) { // memset(go,0,sizeof go); ans=(ans+dfs(n,i))%mod; } if (flag) printf("-1\n"); else printf("%d\n",ans); } void reset() { ans=flag=0; cnt=0; while (!q.empty()) q.pop(); memset(dis,-1,sizeof dis); memset(f,-1,sizeof f); memset(vis,0,sizeof vis); memset(head,0,sizeof head); memset(go,0,sizeof go); } int main() { // freopen("1.in","r",stdin); // freopen("1.out","w",stdout); scanf("%d",&T); while (T--) { reset(); init(); solve(); } return 0; }
这题我一开始打得很快,因为是搜索,比较熟练,但是码完后交上去RE了一个点。这个RE的点我查了很久,为什么会RE。但是我发现我的程序里的错误是 用了NK^2的时间。因为 for (k) memset(nk) ,但是显示的是RE错误。所以,memset应该是调用空间的,RE了可能是因为memset炸空间。
相关文章推荐
- [题解]NOIP2017 Day1 Solution - by xyz32768
- NOIP2017 Day1_T3 逛公园
- NOIP 2017 Day1 题2: 时间复杂度 栈
- 洛谷P3953 逛公园_NOIP2017_DAY1_T3
- NOIP2017_提高组_复赛_DAY1
- 计蒜客 2017 NOIP 提高组模拟赛(二)Day1 A. 邻家男孩
- NOIP 2017 Day1 题3:逛公园 最短路径+动态规划
- NOIP2017 Day1
- NOIP 2017 Day1 总结
- [NOIp2017 Day1 T1] 小凯的疑惑math (数论)
- NOIP 2017 day1 t1
- 【NOIP2017】Day1
- NOIP2017 Day1 T1
- NOIP2017_DAY1
- NOIP2017 Day1 T1 小凯的疑惑 真·奥义·蒟蒻总结
- [NOIp2017 Day1 T2] 时间复杂度complexity(栈,模拟)
- noip2017 Day1 T3 逛公园
- NOIP 2017 Day1 题1:小凯的疑惑 数学问题
- JZOJ5436. 【NOIP2017提高A组集训10.30】Group DP
- JZOJ5184. 【NOIP2017提高组模拟6.29】Gift