牛客練習賽16
阿新 • • 發佈:2018-04-28
mes 編號 其它 ioe true def %s long long #define
A 字典序最大的子序列 > 25960019
一開始潛意識看成了循環,最長子串……
找每個字母最晚出現的位置,那麽比它小的字符必須出現在 在它之後的位置
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <set> 6 #include <map> 7 #include <list> 8 #include <stack> 9 #include <queue> 10#include <vector> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 #define ll long long 15 const long maxn=1e6+50; 16 const ll mod=1e9+7; 17 18 char s[maxn]; 19 long a[27],b[27]; 20 21 int main() 22 { 23 long len,i; 24 scanf("%s",s); 25 len=strlen(s);26 for (i=0;i<=26;i++) 27 a[i]=-1; 28 for (i=0;i<len;i++) 29 a[s[i]-97]=i; 30 b[26]=-1; 31 for (i=25;i>=0;i--) 32 b[i]=max(b[i+1],a[i]); 33 for (i=0;i<len;i++) 34 if (b[s[i]-97+1]<i) 35 printf("%c",s[i]); 36 return 0; 37 }38 /* 39 dsfasfaowjfwoeijwalgkargkwefaweioewajfwo 40 */
B 漂亮的樹 > 25974107
分奇數和偶數,最後的數之間的差值是固定的,如1,2,3,2,1 ; 1,2,2,1
原來的數減去最終的數(以a[1]=x為基準),求出現次數最多的數。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <set> 6 #include <map> 7 #include <list> 8 #include <stack> 9 #include <queue> 10 #include <vector> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 #define ll long long 15 const long maxn=1e5+5; 16 const ll mod=1e9+7; 17 18 long a[maxn],b[maxn*2]; 19 20 int main() 21 { 22 long n,r,i,x; 23 scanf("%ld",&n); 24 a[1]=0; 25 for (i=1;i<=(long)(1.0*n/2);i++) 26 a[i+1]=a[i]+1; 27 for (i=n/2+1;i<=n;i++) 28 a[i]=a[n+1-i]; 29 for (i=0;i<=1e5*2;i++) 30 b[i]=0; 31 for (i=1;i<=n;i++) 32 { 33 scanf("%ld",&x); 34 b[x-a[i]+100000]++; 35 } 36 r=0; 37 for (i=0;i<=1e5*2;i++) 38 r=max(r,b[i]); 39 printf("%ld",n-r); 40 return 0; 41 } 42 /* 43 5 44 1 2 3 2 1 45 4 46 1 2 2 1 47 */
C 任意點 > 25961653
若兩點的橫坐標或縱坐標相等,則它們在同一組,求組數
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <set> 6 #include <map> 7 #include <list> 8 #include <stack> 9 #include <queue> 10 #include <vector> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 #define ll long long 15 const long maxn=1e3+5; 16 const ll mod=1e9+7; 17 18 long x[maxn],y[maxn],n; 19 bool vis[maxn]; 20 21 void dfs(long d) 22 { 23 vis[d]=true; 24 long i; 25 for (i=1;i<=n;i++) 26 if ((x[i]==x[d] || y[i]==y[d]) && !vis[i]) 27 dfs(i); 28 } 29 30 int main() 31 { 32 long i,c; 33 scanf("%ld",&n); 34 for (i=1;i<=n;i++) 35 scanf("%ld%ld",&x[i],&y[i]); 36 for (i=1;i<=n;i++) 37 vis[i]=false; 38 c=0; 39 for (i=1;i<=n;i++) 40 if (!vis[i]) 41 { 42 c++; 43 dfs(i); 44 } 45 printf("%ld",c-1); 46 return 0; 47 }
D k進制數 > 25967939
額,其實要是樣例沒有把解題思路和易錯點說得這麽清晰,那這道題就是好題了……
紙上做模擬,發現當所有位之和為n,則:
n=0,結果為0,
否則,
m=n%(k-1),
如果m=0,則結果為k-1,
否則結果為m。
對結果為0,k-1和其它 分別求解
結果為0:求0的個數。如0,0,0,1,2,3,0,0,2,0,則f(3)+f(2)+f(1)=3*4/2 + 2*3/2 + 1*2/2.
結果為k-1,減去上述為0的個數。
結果為0~k-1:
x(i)記錄前i個數之和,g(i)記錄所有x(j) [j=1..i]中,余數為(i-b+k-1)%(k-1)的個數,從而之後當x(w)=i,以第w位為結尾的子串中,子串和除以(k-1)等於b的個數為g(i)個。
因為內存限制,所以要進行離散化……
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <set> 6 #include <map> 7 #include <list> 8 #include <stack> 9 #include <queue> 10 #include <vector> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 #define ll long long 15 const long maxn=1e5+5; 16 const ll mod=1e9+7; 17 18 long a[maxn],x[maxn],g[maxn*2]; 19 map<long,long>f; 20 set<long>s; 21 22 int main() 23 { 24 long k,b,n,i,j,num,nn; 25 ll ans=0; 26 scanf("%ld%ld%ld",&k,&b,&n); 27 for (i=1;i<=n;i++) 28 scanf("%ld",&a[i]); 29 if (b==0) 30 { 31 for (i=1;i<=n;i++) 32 if (a[i]==0) 33 { 34 j=i; 35 while (i!=n && a[i+1]==0) 36 i++; 37 ans=ans+(long long)(i-j+2)*(i-j+1)/2; 38 } 39 printf("%lld",ans); 40 return 0; 41 } 42 else if (b==k-1) 43 { 44 for (i=1;i<=n;i++) 45 if (a[i]==0) 46 { 47 j=i; 48 while (i!=n && a[i+1]==0) 49 i++; 50 ans=ans-(long long)(i-j+2)*(i-j+1)/2; 51 } 52 b=0; 53 } 54 55 k--; 56 s.clear(); 57 x[0]=0; 58 for (i=1;i<=n;i++) 59 { 60 x[i]=(x[i-1]+a[i])%k; 61 s.insert(x[i]); 62 s.insert((x[i]+b)%k); 63 } 64 s.insert(b); 65 set<long>::iterator z; 66 f.clear(); 67 for (z=s.begin(),num=0;z!=s.end();z++,num++) 68 f[*z]=num; 69 for (i=0;i<num;i++) 70 g[i]=0; 71 g[f[b]]=1; 72 for (i=1;i<=n;i++) 73 { 74 ans=ans+(long long)g[f[x[i]]]; 75 g[f[(x[i]+b)%k]]++; 76 } 77 printf("%lld",ans); 78 return 0; 79 } 80 /* 81 7 6 10 82 0 3 0 0 5 0 4 0 0 0 83 84 85 7 6 5 86 0 0 0 0 0 87 88 7 6 6 89 0 0 0 0 0 6 90 91 7 6 8 92 0 0 0 0 2 4 0 0 93 94 7 6 9 95 0 0 0 0 2 4 0 0 6 96 97 10 5 2 98 1 2 99 */
E 求值 > 25970027
求從某個數開始,第一次 數的第i位為1的數的編號,最多有20個(2^20=1048576),從而時間復雜度O(20n)。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <set> 6 #include <map> 7 #include <list> 8 #include <stack> 9 #include <queue> 10 #include <vector> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 #define ll long long 15 #define inf 1e9 16 const long maxn=1e5+5; 17 const ll mod=1e9+7; 18 19 long a[maxn],nex[maxn][30]; 20 bool vis[maxn][30],use[1048576+5]; 21 long num[30]; 22 23 int main() 24 { 25 long n,b,i,j,k,g; 26 scanf("%ld",&n); 27 for (i=1;i<=n;i++) 28 { 29 scanf("%ld",&a[i]); 30 j=0; 31 b=a[i]; 32 while (b) 33 { 34 if (b & 1) 35 vis[i][j]=1; 36 else 37 vis[i][j]=0; 38 j++; 39 b>>=1; 40 } 41 } 42 for (j=0;j<20;j++) 43 nex[n+1][j]=inf; 44 for (i=n;i>=1;i--) 45 for (j=0;j<20;j++) 46 if (vis[i][j]) 47 nex[i][j]=i; 48 else 49 nex[i][j]=nex[i+1][j]; 50 51 for (i=0;i<1048576;i++) 52 use[i]=0; 53 for (i=1;i<=n;i++) 54 { 55 g=0; 56 for (j=0;j<20;j++) 57 if (nex[i][j]!=inf) 58 { 59 num[g]=nex[i][j]; 60 g++; 61 } 62 sort(num,num+g); 63 k=a[i]; 64 use[k]=1; 65 for (j=0;j<g;j++) 66 { 67 k=k | a[num[j]]; 68 use[k]=1; 69 } 70 } 71 g=0; 72 for (i=0;i<1048576;i++) 73 if (use[i]) 74 g++; 75 printf("%ld",g); 76 return 0; 77 }
F 選值 > 25960795
先對數排序
用兩個變量,求從一個數開始,大於等於該數且差值小於等於d的數的最遠編號,這個編號一直是遞增的,所以O(n)。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <set> 6 #include <map> 7 #include <list> 8 #include <stack> 9 #include <queue> 10 #include <vector> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 #define ll long long 15 const long maxn=1e5+5; 16 const ll mod=1e9+7; 17 18 long a[maxn]; 19 20 int main() 21 { 22 long n,d,i,k; 23 long long r=0,g; 24 scanf("%ld%ld",&n,&d); 25 for (i=1;i<=n;i++) 26 scanf("%ld",&a[i]); 27 k=1; 28 for (i=1;i<=n;i++) 29 { 30 while (k!=n && a[k+1]-a[i]<=d) 31 k++; 32 g=k-i; 33 r=r+g*(g-1)/2; 34 } 35 printf("%lld",r); 36 return 0; 37 }
或者
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <set> 6 #include <map> 7 #include <list> 8 #include <stack> 9 #include <queue> 10 #include <vector> 11 #include <algorithm> 12 #include <iostream> 13 using namespace std; 14 #define ll long long 15 const long maxn=1e5+5; 16 const ll mod=1e9+7; 17 18 long a[maxn]; 19 20 int main() 21 { 22 long n,d,i,j,k; 23 long long r=0,g1,g2; 24 scanf("%ld%ld",&n,&d); 25 for (i=1;i<=n;i++) 26 scanf("%ld",&a[i]); 27 k=1; 28 for (i=1;i<=n;i++) 29 { 30 j=i; 31 while (j!=n && a[j+1]==a[i]) 32 j++; 33 k=max(k,j); 34 while (k!=n && a[k+1]-a[i]<=d) 35 k++; 36 g1=j-i+1; 37 g2=k-j; 38 if (g1>=3) 39 r=r+g1*(g1-1)*(g1-2)/6; 40 if (g1>=2 && g2>=1) 41 r=r+g1*(g1-1)/2*g2; 42 if (g1>=1 && g2>=2) 43 r=r+g1*g2*(g2-1)/2; 44 i=j; 45 } 46 printf("%lld",r); 47 return 0; 48 }
牛客練習賽16