啊 真的挂了 csp再挂就不行了啊
现在普及组的题都挂不到1=了
不能颓废qaq
T1 [NOIP2013 普及组] 表达式求值
https://www.luogu.com.cn/problem/P1981
qaq 炸了 分炸没了
因为前几天写了个表达式的题目就转了后缀表达式求
真香了 char cnt= 0
还tm的是错过的地方
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define Mod 10000
const int N= 1000005; //注意题目中的数据范围是 表达式中加法运算符和乘法运算符的总数≤100000 但是真实情况的话还有数字
struct Node
{
int val;
int is;
};
int num[N], top;
Node fu[N]; int tot;
char ans[N]; int cnt; //char cnt qaq update 2021.10.5 已更正
signed main()
{
string s; cin>> s;
for(int i=0; i<s.size(); i++)
{
if(s[i]== '*') ans[++ cnt]= s[i];
if(s[i]== '+')
{
while(ans[cnt]== '*') fu[++ tot].val= ans[cnt-- ], fu[tot].is= 1;
ans[++ cnt]= '+';
}
if(s[i]>= '0'&& s[i]<= '9')
{
int x= 0;
while(s[i]>= '0'&& s[i]<= '9') x= (x* 10+ s[i]- '0')% Mod, i++;
i-- ;
fu[++ tot].val= x;
}
}
while(cnt) fu[++ tot].val= ans[cnt-- ], fu[tot].is= 1; //转后缀表达式
for(int i=1; i<=tot; i++)
{
if(fu[i].is== 0) num[++ top]= fu[i].val;
else
{
int a= num[top-- ]; int b= num[top-- ];
if(fu[i].val== 43) num[++ top]= (a+ b)% Mod;
else num[++ top]= (a* b)% Mod;
}
} //直接求值
cout<< num[1]% Mod<< endl;
return 0;
} //我可能是最麻烦的方法了 其实这题并不用那么多 直接能乘就乘 能加就加好了
[NOIP2013 普及组] 小朋友的数字
https://www.luogu.com.cn/problem/P1982
小朋友的题都不会做了啊
怎么说 自己坑自己?
考场上发现了会爆long long
然后作茧自缚 写得不对???
原来有80pts的直接挂掉了
好在写了个50pts的部分分
80pts (会爆long long
) 虽然写的是P50
但有80pts
struct P50
{
int a[N], f[N], t[N], h[N];
void solve()
{
for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
f[1]= a[1], t[1]= a[1];
for(int i=2; i<=n; i++)
{
f[i]= max(f[i- 1]+ a[i], a[i]);
t[i]= max(t[i- 1], f[i]);
} //dp求最大连续字段和 其实t数组就是个摆设, f数组也没啥用
h[1]= t[1];
int maxn= -INF; maxn= max(maxn, h[1]+ t[1]);
for(int i=2; i<=n; i++)
{
h[i]= maxn;
maxn= max(maxn, h[i]+ t[i]);
}
maxn= -INF;
for(int i=1; i<=n; i++) maxn= max(maxn, h[i]); //模拟题
if(maxn< 0)
{
cout<< '-';
maxn= abs(maxn);
} //听说还有-0什么的 不过没卡
cout<< maxn% p<< endl;
}
}P50;
发现要写高精 懒得写 怎么办呢 错误的代码:
//其实可以发现就是上面的代码加上两个函数2333
//不要怀疑 因为我就是这样改的
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF (int)1e18
const int N= 1000005;
struct Node
{
int s; int y;
}a[N], f[N], t[N], h[N];
int n, p;
Node add(Node a, Node b)
{
Node c; c.s= a.s+ b.s;
c.y= a.y+ b.y; if(c.y/ p!= 0) c.s+= c.y/ p, c.y%= p;
return c;
}
Node Max(Node a, Node b)
{
if(a.s> b.s) return a;
else if(a.s< b.s) return b;
else if(a.y> b.y) return a;
else return b;
}
signed main()
{
cin>> n>> p;
for(int i=1; i<=n; i++)
{
int x; scanf("%lld", &x);
a[i].s= x/ p; a[i].y= x% p;
}
f[1]= a[1], t[1]= a[1];
for(int i=2; i<=n; i++)
{
f[i]= Max(add(f[i- 1], a[i]), a[i]);
t[i]= Max(t[i- 1], f[i]);
}
h[1]= t[1];
Node maxn; maxn.s= -INF; maxn= Max(maxn, add(h[1], t[1]));
for(int i=2; i<=n; i++)
{
h[i]= maxn;
maxn= Max(maxn, add(h[i], t[i]));
}
maxn.s= -INF;
for(int i=1; i<=n; i++) maxn= Max(maxn, h[i]);
if(maxn.y< 0)
{
cout<< '-';
maxn.y= abs(maxn.y);
}
cout<< maxn.y% p<< endl;
return 0;
}
这是考场上部分代码 剩下的因为太乱和源码丢失就不放了
这是错的 20pts 为什么?
看起来很有道理啊
add太草率了
Node add(Node a, Node b)
{
Node c; c.s= a.s+ b.s;
c.y= a.y+ b.y; //他炸掉了
//In this way
if(c.s>= 0&& c.y>= p) c.s+= c.y/ p, c.y= c.y% p; //如果余数同符号 一切都好
if(c.s<= 0&& c.y<= -p) c.s+= c.y/ p, c.y= c.y% p;
if(c.s> 0&& c.y< 0) c.s-- , c.y+= p; //不然我们不能直接搞 不可能a*p+b然后b是负的吧
if(c.s< 0&& c.y>= p) c.s++ , c.y-= p;
return c;
}
莫名其妙地Accept了
还有另外一种写法 智商什么的吊打高精度
不过这种高精度法也可以应用什么的 用于小的高精度 100位什么的不要找我啊qaq
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N= 1000005;
int a[N], t[N];
signed main()
{
int n, p; cin>> n>> p;
for(int i= 1; i<= n; i++ ) scanf("%lld", &a[i]);
int sum= - (int)1e18;
for(int i= 1; i<= n; i++ )
{
sum= max(sum+ a[i], a[i]);
t[i]= sum;
}
for(int i= 2; i<= n; i++ ) t[i]= max(t[i], t[i- 1]);
int flag= 0;
for(int i= 2; i<= n; i++)
if(t[i]> abs(t[1]))
{
flag= 1; break;
}
if(! flag)
{
cout<< t[1]% p<< endl;
return 0;
}
int maxn= 2* t[1]% p;
for(int i= 3; i<= n; i++ )
maxn= (maxn+ max((int)0, t[i- 1]))% p;
cout<< maxn% p<< endl;
return 0;
}
其实我并没有懂qaq
有dalao能教教我吗qaq
T3
[NOIP2013 普及组] 车站分级
https://www.luogu.com.cn/problem/P1983
真的老题了
但我再次写的是暴力 luogu坑人qaq
正解 不用所有都连边 只要找个中转点就行了
这题虽然邻接矩阵存最好 但我是链式前向星存的
#include <bits/stdc++.h>
using namespace std;
const int N= 2005, M= N* N;
int in[N], h[N], e[M], ne[M], idx;
int dist[N], vis[N];
void add(int a, int b)
{
e[idx]= b, ne[idx]= h[a], h[a]= idx++ ;
return ;
}
int main()
{
int n, m; cin>> n>> m;
memset(h, -1, sizeof h);
for(int i= 1; i<= m; i++ )
{
int x; scanf("%d", &x);
memset(vis, 0, sizeof vis);
int st= n, ed= 0;
for(int j= 1; j<= x; j++ )
{
int y; scanf("%d", &y); vis[y]= 1;
add(y, i+ n); in[i+ n]++ ; //可能叫找虚点什么的
st= min(st, y); ed= max(ed, y);
}
for(int j= st; j<= ed; j++ )
{
if(vis[j]) continue;
add(i+ n, j); in[j]++ ; //存拓扑排序
}
}
queue<int> q;
for(int i= 1; i<= n+ m; i++ )
if(! in[i]) q.push(i);
while(q.size())
{
int u= q.front(); q.pop();
for(int i= h[u]; ~ i; i= ne[i])
{
int j= e[i];
dist[j]= max(dist[j], dist[u]+ 1); //找最长链
in[j]-- ;
if(! in[j]) q.push(j);
}
}
int maxn= 0;
for(int i= 1; i<= n; i++ ) maxn= max(maxn, dist[i]);
cout<< (maxn+ 1)/ 2+ 1<< endl;
return 0;
}