日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2018/7/7-纪中某C组题【jzoj1494,jzoj1495,jzoj1496,jzoj1497】

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2018/7/7-纪中某C组题【jzoj1494,jzoj1495,jzoj1496,jzoj1497】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

290卡成145,十分開心。


正題


T1:密碼

大意

N個數乘起來

考試時

看起來十分簡單的高精乘單精

解題思路

10241024其實是10241024高精乘高精了解一下,30分QAQ

代碼(高精乘高精我就不解釋了吧)

#include<cstdio> #include<cstring> #define M 2500 using namespace std; long long a[M+1],n,k[M],b[M+1],l,lo; void read() {memset(k,0,sizeof(k));char c[51];scanf("%s",c);l=strlen(c);for (int i=1;i<=l;i++)k[i]=c[l-i]-48; } void add() {for (int i=1;i<=lo;i++){for (int j=1;j<=l;j++){b[i+j-1]+=a[i]*k[j];b[i+j]+=b[i+j-1]/10;b[i+j-1]%=10;}}lo=-1;for (int i=M;i>=1;i--){if (b[i]!=0&&lo==-1) lo=i;a[i]=b[i];b[i]=0;} } void write() {int w=M;while (w>1&&!a[w]) w--;int flag=w;for (;w;w--)printf("%d",a[w]); } int main() {scanf("%d",&n);a[1]=1;lo=1;for (int i=1;i<=n;i++){read();add();}write(); }

T2:寶石

大意

有一個m?mm?m的矩陣,然后nn個寶石價值不同在矩陣里,然后一個為k?kk?k的東西要求碰到大寶石價值最大。

考試時

敲了一個矩陣前綴和然后O(n2)O(n2)暴力枚舉拿了60分

解題思路

定義一個長度m,高度為k的掃描線,然后在線內的用線段樹維護最大長度為k的字段和。

代碼

#include<cstdio> #include<algorithm> using namespace std; struct treenode{int l,r,w,lazy; }a[300001]; struct node{int x,y,w; }d[50001]; int m,n,k,maxs; void build(int k,int l,int r) {a[k].l=l;a[k].r=r;if (l==r) return;int mid=(l+r)/2;build(k*2,l,mid);build(k*2+1,mid+1,r); } void ddata(int k) {a[k*2].w+=a[k].lazy;a[k*2+1].w+=a[k].lazy;a[k*2].lazy+=a[k].lazy;a[k*2+1].lazy+=a[k].lazy;a[k].lazy=0; } void updata(int l,int r,int k,int num) {if (a[k].l==l&&a[k].r==r){a[k].w+=num;a[k].lazy+=num;return;}ddata(k);if (a[k*2].r>=r) updata(l,r,k*2,num);else if (a[k*2+1].l<=l) updata(l,r,k*2+1,num);else updata(l,a[k*2].r,k*2,num),updata(a[k*2+1].l,r,k*2+1,num);a[k].w=max(a[k*2].w,a[k*2+1].w); } //以上為線段樹 bool cmp(node x,node y) {return x.y<y.y; } int main() {scanf("%d%d%d",&m,&n,&k);for (int i=1;i<=n;i++){scanf("%d%d%d",&d[i].x,&d[i].y,&d[i].w);}sort(d+1,d+1+n,cmp);//排序build(1,1,m);//建樹int w=1;//掃描上限for (int i=1;i<=n;i++)//枚舉下限{while (d[i].y-d[w].y>k)//更新上限{updata(d[w].x,min(d[w].x+k,m),1,-d[w].w);//去掉w++;}updata(d[i].x,min(d[i].x+k,m),1,d[i].w);//維護字段和maxs=max(maxs,a[1].w);//查詢最大字段和}printf("%d",maxs); }

T3:頁

大意

一個序列,每次取中間的放到頭或尾,求至少多少次可以變為單調遞增。

考試

剛開始打了個貪心,然后發現數據不是很大,然后打了一個廣搜,為了防止超時打了一個卡時間的結果就炸了30。把卡時間的去掉后100

解題思路

廣搜然后map庫(或哈希表)去重

代碼

#include<cstdio> #include<map> #include<string> #include<iostream> #include<queue> #include<ctime> using namespace std; map<string,int> f; string s,mb,state[362881]; int a[10],n,head,tail; void bfs() {if (s==mb){printf("0");return;}state[1]=s;f[s]=1;head=0;tail=1;do{s=state[++head];int k=f[state[head]];for (int i=1;i<=n/2;i++)swap(s[i],s[n/2+1]);//放在頭if (!f[s]){state[++tail]=s;f[s]=k+1;if (s==mb)//已經完成{printf("%d",k);return;}}s=state[head];for (int i=n;i>n/2+1;i--)swap(s[i],s[n/2+1]);//放在尾if (!f[s]){state[++tail]=s;f[s]=k+1;if (s==mb)//已經完成{printf("%d",k);return;}}}while (head<tail);printf("No Answer"); } int main() {scanf("%d",&n);s+="*";mb+="*";for (int i=1;i<=n;i++){scanf("%d",&a[i]);s+=i+48;mb+=i+48;}for (int i=1;i<n;i++)for (int j=i+1;j<=n;j++){if (a[i]>a[j]){swap(a[i],a[j]);swap(mb[i],mb[j]);//確定目標狀態}}bfs();return 0; }

T4:景點中心

大意

有n個景點構成一顆樹,然后每個景點有不同數量的學生,邊有不同的長度,定一個景點為中心要求所有學生到達這個點的路徑長度和最小。

考試

敲出了正解,結果沒注意范圍30QAQ。

解題思路

一棵樹然后就想到了樹形dp,然后想起來有個東西叫二次掃描換根法,之后就推出了正解:

首先我們先以1為根進行一遍求出f[i]f[i]zn[i]zn[i]f[i]f[i]是表示點i子樹的學生走到點i的路徑長度和,然后zn[i]zn[i]表示點i的子樹的學生人數總和。

然后我們就求出了以i為根節點的情況下的路徑和,我們嘗試推到第二層的節點。

這是一顆以1為根節點的樹,然后我們變為以2為根節點

然后我們會發現

圖中綠色部分(原第二個節點的子樹部分)都少走了一條路w,而圖中紅色部分(其余部分)都多走了一條路w,所以我們可以自己計算:

c[x]=c[father]+(zn[1]?zn[x])?w?zn[x]?wc[x]=c[father]+(zn[1]?zn[x])?w?zn[x]?w
從而 O(1)O(1)的時間復雜度內計算出下一個點為根時的距離和。

代碼

#include<cstdio> #include<algorithm> #include<cstring> #define N 1000001 using namespace std; struct node{int next,to,w; }a[N]; int ls[N],tot,n,x,y,w,v[N]; long long c[N],f[N],zn[N],maxs,num[N]; void addl(int x,int y,int w) {a[++tot].to=y;a[tot].w=w;a[tot].next=ls[x];ls[x]=tot; } void dp(int x,int dep)//第一次掃描 {v[x]=true;zn[x]=num[x];//記錄人數f[x]=num[x]*dep;//統計for (int i=ls[x];i;i=a[i].next){int y=a[i].to;if (!v[y]){dp(y,dep+a[i].w);f[x]+=f[y];zn[x]+=zn[y];//累計}} } void zdp(int x,int dep,int fa,int from)//第二次掃描 {v[x]=true;if (x!=1)c[x]=c[fa]+(zn[1]-zn[x])*a[from].w-zn[x]*a[from].w;//計算if (c[x]<c[maxs]) maxs=x;for (int i=ls[x];i;i=a[i].next){y=a[i].to;if (!v[y])zdp(y,dep+a[i].w,x,i);//計算子節點} } int main() {freopen("data.txt","r",stdin);scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%lld",&num[i]);}for (int i=1;i<n;i++){scanf("%d%d%d",&x,&y,&w);addl(x,y,w);addl(y,x,w);}c[0]=1e18;maxs=0;dp(1,0);memset(v,0,sizeof(v));c[1]=f[1];zdp(1,0,0,0);printf("%lld\n%lld",maxs,c[maxs]); }

后續

zyc大佬太強了

m e | \ /V / / ====== / / orz orz orz orz orz orz orz orz orz/ / ====== / / orz orz orz orz orz orz orz orz orz+ =========== + orz orz orz orz orz orz orz orz orz| [zyc dalao] | orz orz orz orz orz orz orz orz orz+ =========== + orz orz orz orz orz orz orz orz orz\ \ ====== \ \ orz orz orz orz orz orz orz orz orz\ \ ====== \ \ orz orz orz orz orz orz orz orz orz

總結

以上是生活随笔為你收集整理的2018/7/7-纪中某C组题【jzoj1494,jzoj1495,jzoj1496,jzoj1497】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。