1. 程式人生 > 其它 >離線賽總結2

離線賽總結2

啊 真的掛了 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

未來可期。