考研狗的日常休闲活动。
Update:3/11日停更,刷PAT的题目去了。
2019/2/16
CF 1113A Sasha and His Trip
第一站先把油桶加满,后面每到一站判断油箱内的油能否支持开到最后,不能的话加一升油(花费$i$元)。思路就是尽量在前面站加油。


1 #include <set>
2 #include <map>
3 #include <queue>
4 #include <deque>
5 #include <stack>
6 #include <cmath>
7 #include <cstdio>
8 #include <vector>
9 #include <string>
10 #include <cstring>
11 #include <fstream>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 #define eps 1e-8
17 #define pb push_back
18 #define PI acos(-1.0)
19 #define INF 0x3f3f3f3f
20 #define clr(a,b) memset(a,b,sizeof(a)
21 #define bugc(_) cerr << (#_) << " = " << (_) << endl
22 #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
23
24 typedef long long ll;
25 typedef unsigned long long ull;
26
27 int main(){
28 FAST_IO;
29 int n,v,cost=0;
30 cin>>n>>v;
31 if(v>=n-1){
32 cout<<n-1<<endl;
33 return 0;
34 }
35 cout<<v+(2+n-v)*(n-v-1)/2<<endl;
36 return 0;
37 }
2019/2/17
CF 1113B Sasha and Magnetic Machines
两个数中乘上$x$的一定是所有数中最小的,再枚举剩下的数($ai<=100$),每个数再枚举其因子,过程中更新答案。


1 #include <set>
2 #include <map>
3 #include <queue>
4 #include <deque>
5 #include <stack>
6 #include <cmath>
7 #include <cstdio>
8 #include <vector>
9 #include <string>
10 #include <cstring>
11 #include <fstream>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 #define eps 1e-8
17 #define pb push_back
18 #define PI acos(-1.0)
19 #define INF 0x3f3f3f3f
20 #define clr(a,b) memset(a,b,sizeof(a)
21 #define bugc(_) cerr << (#_) << " = " << (_) << endl
22 #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
23
24 typedef long long ll;
25 typedef unsigned long long ull;
26 const int N=5e4+10;
27 int a[N];
28
29 int main(){
30 FAST_IO;
31 int n,sum=0,ans=INF;
32 cin>>n;
33 for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
34 ans=sum;
35 sort(a+1,a+1+n);
36 for(int i=2;i<=n;i++){
37 for(int j=1;j*j<=a[i];j++){
38 if(a[i]%j==0){
39 ans=min(ans,sum-a[1]-a[i]+a[1]*j+a[i]/j);
40 }
41 }
42 }
43 cout<<ans<<endl;
44 return 0;
45 }
2/18
CF 1113C Sasha and a Bit of Relax
$pre[i]$表示前缀异或值。若$pre[i]$和$pre[j]$相同,且$i<j$,说明$(i,j]$异或值为0,那么从中取出任意个进行异或得到的值 和 剩下的数异或得到的值相等,所以只要保证$j-i$为偶数即可。
操作的话,奇数位置和偶数位置分别记录下即可。


1 #include <set>
2 #include <map>
3 #include <queue>
4 #include <deque>
5 #include <stack>
6 #include <cmath>
7 #include <cstdio>
8 #include <vector>
9 #include <string>
10 #include <cstring>
11 #include <fstream>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 #define eps 1e-8
17 #define pb push_back
18 #define PI acos(-1.0)
19 #define INF 0x3f3f3f3f
20 #define clr(a,b) memset(a,b,sizeof(a)
21 #define bugc(_) cerr << (#_) << " = " << (_) << endl
22 #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
23
24 typedef long long ll;
25 typedef unsigned long long ull;
26 map <ll,ll> odd,even;
27
28 int main(){
29 FAST_IO;
30 ll n,num,tmp=0,ans=0,mx=0;
31 cin>>n;
32 even[0]++;
33 for(ll i=1;i<=n;i++){
34 cin>>num;
35 tmp=tmp^num;
36 mx=max(mx,tmp);
37 if(i%2==1) odd[tmp]++;
38 else even[tmp]++;
39 }
40 for(ll i=0;i<=mx;i++){
41 ans+=odd[i]*(odd[i]-1)/2;
42 ans+=even[i]*(even[i]-1)/2;
43 }
44 cout<<ans<<endl;
45 return 0;
46 }
2/19
CF 1113D Sasha and One More Name
长度为n的字符串,大于等于n-1个相同字符Impossible;切一刀的情况,每个位置遍历一下,找到符合条件;剩余的情况都是切两刀的。


1 #include <set>
2 #include <map>
3 #include <queue>
4 #include <deque>
5 #include <stack>
6 #include <cmath>
7 #include <cstdio>
8 #include <vector>
9 #include <string>
10 #include <cstring>
11 #include <fstream>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 #define eps 1e-8
17 #define pb push_back
18 #define PI acos(-1.0)
19 #define INF 0x3f3f3f3f
20 #define clr(a,b) memset(a,b,sizeof(a)
21 #define bugc(_) cerr << (#_) << " = " << (_) << endl
22 #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
23
24 typedef long long ll;
25 typedef unsigned long long ull;
26 map <char,int> mp;
27
28 bool check(string s,string p){
29 if(s==p) return false;
30 int m=s.size();
31 for(int i=0;i<m/2;i++){
32 if(s[i]!=s[m-1-i]) return false;
33 }
34 return true;
35 }
36
37 int main(){
38 FAST_IO;
39 string str,s1,s2,s;
40 cin>>str;
41 int n=str.size();
42 for(int i=0;i<n;i++){
43 char c=str[i];
44 mp[c]++;
45 if(mp[c]>=n-1){
46 cout<<"Impossible"<<endl;
47 return 0;
48 }
49 }
50 for(int i=1;i<n;i++){
51 s1=str.substr(0,i);
52 s2=str.substr(i,n-i);
53 s=s2+s1;
54 if(check(s,str)){
55 cout<<1<<endl;
56 return 0;
57 }
58 }
59 cout<<2<<endl;
60 return 0;
61 }
2/20
CF 1117A Best Subsegment
找最长连续最大数串。


1 #include <set>
2 #include <map>
3 #include <queue>
4 #include <deque>
5 #include <stack>
6 #include <cmath>
7 #include <cstdio>
8 #include <vector>
9 #include <string>
10 #include <cstring>
11 #include <fstream>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 #define eps 1e-8
17 #define pb push_back
18 #define PI acos(-1.0)
19 #define INF 0x3f3f3f3f
20 #define clr(a,b) memset(a,b,sizeof(a)
21 #define bugc(_) cerr << (#_) << " = " << (_) << endl
22 #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
23
24 typedef long long ll;
25 typedef unsigned long long ull;
26 const int N=1e5+10;
27 int a[N];
28
29 int main(){
30 FAST_IO;
31 int n,mx=0,ans=0;
32 cin>>n;
33 for(int i=1;i<=n;i++) cin>>a[i],mx=max(mx,a[i]);
34 for(int i=1;i<=n;i++){
35 if(a[i]==mx){
36 int cnt=1,j=i;
37 for(j=i+1;j<=n;j++){
38 if(a[j]==a[i]) cnt++;
39 else break;
40 }
41 i=j;
42 ans=max(ans,cnt);
43 }
44 }
45 cout<<ans<<endl;
46 return 0;
47 }
CF 1117B Emotes
配k个最大值和1个次大值为一组,m个位置一组一组地填进去,剩下的再用最大值填。


1 #include <set>
2 #include <map>
3 #include <queue>
4 #include <deque>
5 #include <stack>
6 #include <cmath>
7 #include <cstdio>
8 #include <vector>
9 #include <string>
10 #include <cstring>
11 #include <fstream>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 #define eps 1e-8
17 #define pb push_back
18 #define PI acos(-1.0)
19 #define INF 0x3f3f3f3f
20 #define clr(a,b) memset(a,b,sizeof(a)
21 #define bugc(_) cerr << (#_) << " = " << (_) << endl
22 #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
23
24 typedef long long ll;
25 typedef unsigned long long ull;
26 const int N=2e5+10;
27 ll a[N];
28
29 int main(){
30 FAST_IO;
31 ll n,m,k;
32 cin>>n>>m>>k;
33 for(ll i=1;i<=n;i++) cin>>a[i];
34 sort(a+1,a+1+n);
35 ll t=m/(k+1);
36 cout<<t*(k*a[n]+a[n-1])+(m%(k+1))*a[n]<<endl;
37 return 0;
38 }
2/21
CF 1117C Magic Ship
二分下答案。先统计mid天靠风能跑到哪个位置,然后去凑。注意left==right的时候也要判断下,不然会漏。


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 typedef long long ll;
8 const int N=1e5+10;
9 char s[N];
10 ll n,x1,y1,x2,y2;
11 ll L=0,R=0,U=0,D=0;
12
13 bool check(ll mid){
14 ll time=mid/n;
15 ll l=time*L,r=time*R,u=time*U,d=time*D;
16 for(int i=1;i<=(mid%n);i++){
17 if(s[i]=='L') l++;
18 else if(s[i]=='R') r++;
19 else if(s[i]=='U') u++;
20 else if(s[i]=='D') d++;
21 }
22 //r
23 ll p=0;
24 if(x2>=x1){
25 p=(x2-x1)-(r-l);
26 if(mid<abs(p)) return false;
27 else mid-=abs(p);
28 }
29 //l
30 else{
31 p=(x1-x2)-(l-r);
32 if(mid<abs(p)) return false;
33 else mid-=abs(p);
34 }
35 //u
36 if(y2>=y1){
37 p=(y2-y1)-(u-d);
38 if(mid<abs(p)) return false;
39 else mid-=abs(p);
40 }
41 //d
42 else{
43 p=(y1-y2)-(d-u);
44 if(mid<abs(p)) return false;
45 else mid-=abs(p);
46 }
47 return true;
48 }
49
50 int main(){
51 scanf("%lld%lld%lld%lld%lld",&x1,&y1,&x2,&y2,&n);
52 scanf("%s",s+1);
53 for(int i=1;i<=n;i++){
54 if(s[i]=='L') L++;
55 else if(s[i]=='R') R++;
56 else if(s[i]=='U') U++;
57 else if(s[i]=='D') D++;
58 }
59 ll mid,left=0,right=1e18,ans=1e18;
60 while(left<=right){
61 mid=(left+right)/2;
62 if(check(mid)) ans=min(ans,mid),right=mid-1;
63 else left=mid+1;
64 }
65 if(ans==1e18) printf("-1\n");
66 else printf("%lld\n",ans);
67 return 0;
68 }
2/22
CF 1118A Water Buying
判断下2a和b的大小。


1 #include <cstdio>
2 #include <iostream>
3 #include <algorithm>
4 using namespace std;
5
6 typedef long long ll;
7
8 int main(){
9 int q;
10 cin>>q;
11 while(q--){
12 ll n,a,b;
13 cin>>n>>a>>b;
14 if(2*a<=b) cout<<n*a<<endl;
15 else{
16 cout<<b*(n/2)+(n%2)*a<<endl;
17 }
18 }
19 return 0;
20 }
CF 1118B Tanya and Candies
奇数和偶数位置前缀分别记录下,如果某个位置拿掉,那么该位置的前面奇数偶数位置不变,后面奇变偶,偶变奇。


1 #include <cstdio>
2 #include <iostream>
3 #include <algorithm>
4 using namespace std;
5
6 const int N=2e5+10;
7 int a[N],odd[N],even[N];
8
9 int main(){
10 int n,ans=0;
11 scanf("%d",&n);
12 for(int i=1;i<=n;i++){
13 scanf("%d",&a[i]);
14 odd[i]=odd[i-1];
15 even[i]=even[i-1];
16 if(i%2) odd[i]+=a[i];
17 else even[i]+=a[i];
18 }
19 for(int i=1;i<=n;i++){
20 int sum1=odd[i-1]+even[n]-even[i];
21 int sum2=even[i-1]+odd[n]-odd[i];
22 if(sum1==sum2) ans++;
23 }
24 printf("%d\n",ans);
25 return 0;
26 }
2/23
CF 1118C Palindromic Matrix
使劲模拟,注意细节,大力出奇迹。


1 #include <map>
2 #include <cstdio>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 const int N=2010;
8 int a[N],num[N];
9 int ans[N][N];
10 bool vis[N];
11 map <int,int> m;
12
13 int main(){
14 int n,cnt=0;
15 scanf("%d",&n);
16 for(int i=1;i<=n*n;i++) scanf("%d",&a[i]),m[a[i]]++;
17 for(int i=1;i<=n*n;i++){
18 if(!vis[a[i]]){
19 num[++cnt]=a[i];
20 vis[a[i]]=1;
21 }
22 }
23
24 //n/2
25 int x=1,y=1;
26 for(int i=1;i<=cnt;i++){
27 if(m[num[i]]%2){
28 if(n%2==0) {printf("NO\n");return 0;}
29 else{
30 if(ans[n/2+1][n/2+1]!=0) {printf("NO\n");return 0;}
31 else{
32 ans[n/2+1][n/2+1]=num[i];
33 m[num[i]]--;
34 }
35 }
36 }
37 if(n%2==0&&m[num[i]]%4!=0) {printf("NO\n");return 0;}
38 int time=m[num[i]]/4;
39 for(int j=1;j<=time;j++){
40 if(y>n/2){
41 x++;
42 y=1;
43 if(x>n/2) break;
44 }
45 ans[x][y]=ans[x][n-y+1]=ans[n-x+1][y]=ans[n-x+1][n-y+1]=num[i];
46 y++;
47 m[num[i]]-=4;
48 }
49 if(x>n/2) break;
50 }
51
52 //奇数单独补充
53 x=1;y=n/2+1;
54 for(int i=1;i<=cnt;i++){
55 int time=m[num[i]]/2;
56 //cout<<num[i]<<" "<<m[num[i]]<<endl;
57 for(int j=1;j<=time;j++){
58 ans[x][y]=ans[n-x+1][y]=num[i];
59 x++;
60 m[num[i]]-=2;
61 if(x==(n/2+1)) break;
62 }
63 if(x==n/2+1) break;
64 }
65
66 x=n/2+1;y=1;
67 for(int i=1;i<=cnt;i++){
68 int time=m[num[i]]/2;
69 //cout<<num[i]<<" "<<m[num[i]]<<endl;
70 for(int j=1;j<=time;j++){
71 ans[x][y]=ans[x][n-y+1]=num[i];
72 y++;
73 m[num[i]]-=2;
74 if(y==(n/2+1)) break;
75 }
76 if(y==(n/2+1)) break;
77 }
78
79 for(int i=1;i<=cnt;i++){
80 if(m[num[i]]%2){
81 if(n%2==0) {printf("NO\n");return 0;}
82 else{
83 if(ans[n/2+1][n/2+1]!=0) {printf("NO\n");return 0;}
84 else{
85 ans[n/2+1][n/2+1]=num[i];
86 m[num[i]]--;
87 }
88 }
89 }
90 }
91
92 //检测
93 for(int i=1;i<=n;i++)
94 for(int j=1;j<=n;j++){
95 if(ans[i][j]==0) {printf("NO\n");return 0;}
96 }
97
98 printf("YES\n");
99 for(int i=1;i<=n;i++){
100 for(int j=1;j<=n;j++){
101 printf("%d",ans[i][j]);
102 if(j==n) printf("\n");
103 else printf(" ");
104 }
105 }
106 return 0;
107 }
2/24
CF 1118F1 Tree Cutting (Easy Version)
DFS遍历下树,以父亲节点和儿子节点分开,判断儿子节点的子树是否拿全了其中一种颜色,并且没有另一种颜色。


1 #include <vector>
2 #include <cstdio>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 const int N=3e5+10;
8 int a[N],b[N],r[N],n,ans=0;
9 vector <int> E[N];
10
11 void dfs(int x,int fa){
12 if(a[x]==1) b[x]++;
13 else if(a[x]==2) r[x]++;
14 for(int i=0;i<E[x].size();i++){
15 int u=E[x][i];
16 if(u!=fa){
17 dfs(u,x);
18 b[x]+=b[u];
19 r[x]+=r[u];
20 if( (b[u]==b[0]&&!r[u]) || (r[u]==r[0]&&!b[u]) ) ans++;
21 }
22 }
23 }
24
25 int main(){
26 scanf("%d",&n);
27 for(int i=1;i<=n;i++){
28 scanf("%d",&a[i]);
29 if(a[i]==1) b[0]++;
30 else if(a[i]==2) r[0]++;
31 }
32 for(int i=1;i<n;i++){
33 int u,v;
34 scanf("%d%d",&u,&v);
35 E[u].push_back(v);
36 E[v].push_back(u);
37 }
38 dfs(1,0);
39 printf("%d\n",ans);
40 return 0;
41 }
2/25
CF 1118D1 Coffee and Coursework (Easy version)
暴力枚举答案,时间复杂度O(n^2)


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 int a[110];
8 const int INF=0x3f3f3f3f;
9 int n,m,sum=0,ans=INF;
10
11 bool check(int k){
12 int cnt=0,id=0,cost=0;
13 for(int i=1;i<=n;i++){
14 id++;
15 if(id>k) id=1,cost++;
16 cnt+=a[i]-cost;
17 if(cnt>=m) return true;
18 }
19 return false;
20 }
21
22 bool cmp(int x,int y){
23 return x>y;
24 }
25
26 int main(){
27 scanf("%d%d",&n,&m);
28 for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
29 sort(a+1,a+1+n,cmp);
30 for(int i=n;i>=1;i--){
31 if(check(i)) ans=min(ans,i);
32 }
33 if(ans==INF) printf("-1\n");
34 else printf("%d\n",ans);
35 return 0;
36 }
CF 1118D2 Coffee and Coursework (Hard Version)
二分下答案,时间复杂度O(nlogn)


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 typedef long long ll;
8 const int N=2e5+10;
9 ll a[N];
10 int n,m,ans=N;
11
12 bool check(int k){
13 int id=0;
14 ll cnt=0,cost=0;
15 for(int i=1;i<=n;i++){
16 id++;
17 if(id>k) id=1,cost++;
18 cnt+=a[i]-cost;
19 if(cnt>=m) return true;
20 }
21 return false;
22 }
23
24 bool cmp(ll x,ll y){
25 return x>y;
26 }
27
28 int main(){
29 scanf("%d%d",&n,&m);
30 for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
31 sort(a+1,a+1+n,cmp);
32 int l=1,r=n;
33 while(l<=r){
34 int mid=(l+r)/2;
35 if(check(mid)) ans=min(ans,mid),r=mid-1;
36 else l=mid+1;
37 }
38 if(ans==N) printf("-1\n");
39 else printf("%d\n",ans);
40 return 0;
41 }
2/26
CF 1118E Yet Another Ball Problem
左右两列都搞1到k,然后把右边那列上移。最多能有k*(k-1)种,举个例子
1 1 1 2 1 3
2 2 2 3 2 1
3 3 3 1 3 2


1 #include <cstdio>
2 #include <iostream>
3 #include <algorithm>
4 using namespace std;
5
6 int main(){
7 int n,k;
8 scanf("%d%d",&n,&k);
9 if(1LL*n>1LL*(k-1)*k) {printf("NO\n");return 0;}
10 printf("YES\n");
11 for(int i=2;i<=k;i++){
12 int num=i;
13 for(int j=1;j<=k;j++){
14 printf("%d %d\n",j,num++);
15 n--;
16 if(n==0) return 0;
17 if(num==k+1) num=1;
18 }
19 }
20 return 0;
21 }
2/27
CF 1131F Asya And Kittens
并查集维护下右边。


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 const int N=150000+10;
8 int fa[N],r[N],ed[N];
9
10 int fi(int x){
11 return x==fa[x]?x:fa[x]=fi(fa[x]);
12 }
13
14 int main(){
15 for(int i=1;i<=N;i++) fa[i]=ed[i]=i;
16 int n;
17 scanf("%d",&n);
18 for(int i=1;i<n;i++){
19 int u,v;
20 scanf("%d%d",&u,&v);
21 int fx=fi(u),fy=fi(v);
22 fa[fy]=fx;r[ed[fx]]=fy;ed[fx]=ed[fy];
23 }
24 for(int i=1;i<=n;i++){
25 if(fa[i]==i){
26 for(int j=i;j;j=r[j]) printf("%d ",j);
27 return 0;
28 }
29 }
30 return 0;
31 }
2/28
CF 1131D Gourmet choice
除去$=$的条件就是道裸的拓扑排序,$=$的情况只要用并查集缩下点就可以了。


1 #include <queue>
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7
8 const int N=1234;
9 char s[N][N];
10 int n,m,fa[2*N],in[2*N],ans[2*N];
11 vector <int> E[2*N];
12
13 int fi(int x){
14 return x==fa[x]?x:fa[x]=fi(fa[x]);
15 }
16
17 void init(){
18 for(int i=0;i<2*N;i++) fa[i]=i;
19 }
20
21 bool toposort(){
22 queue <int> Q;
23 for(int i=1;i<=n+m;i++) if(i==fi(i)&&in[i]==0) Q.push(i),ans[i]=1;
24 while(!Q.empty()){
25 int u=Q.front();
26 Q.pop();
27 for(int i=0;i<E[u].size();i++){
28 int v=E[u][i];
29 in[v]--;
30 if(in[v]==0) Q.push(v),ans[v]=ans[u]+1;
31 }
32 }
33 for(int i=1;i<=n+m;i++) if(ans[fi(i)]==0) return false;
34 return true;
35 }
36
37 int main(){
38 init();
39 scanf("%d%d",&n,&m);
40 for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
41 for(int i=1;i<=n;i++)
42 for(int j=1;j<=m;j++)
43 if(s[i][j]=='=') fa[fi(j+n)]=fa[fi(i)];
44
45 for(int i=1;i<=n;i++)
46 for(int j=1;j<=m;j++)
47 if(s[i][j]=='<') E[fi(i)].push_back(fi(n+j)),in[fi(n+j)]++;
48 else if(s[i][j]=='>') E[fi(n+j)].push_back(fi(i)),in[fi(i)]++;
49
50 if(!toposort()) printf("No\n");
51 else{
52 printf("Yes\n");
53 for(int i=1;i<=n;i++) printf("%d ",ans[fi(i)]);
54 printf("\n");
55 for(int i=1;i<=m;i++) printf("%d ",ans[fi(n+i)]);
56 }
57 return 0;
58 }
2019/3/1
CF 1130D1 Toy Train (Simplified)
先把每个点处理,计算该点运送完需要的时间;遍历每个点时给它绕一圈,找到时间最长的那个,那个就是把所有运送完所需的时间。注意如果没有货物,需要跳过该点。


1 #include <vector>
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7
8 const int N=222;
9 const int INF=0x3f3f3f3f;
10 int ans[N];
11 vector <int> s[N];
12
13 int main(){
14 int n,m;
15 scanf("%d%d",&n,&m);
16 for(int i=1;i<=m;i++){
17 int a,b;
18 scanf("%d%d",&a,&b);
19 s[a].push_back(b);
20 }
21 for(int i=1;i<=n;i++){
22 int mi=INF;
23 for(int j=0;j<s[i].size();j++){
24 int u=s[i][j];
25 if(u>=i) mi=min(mi,u-i);
26 else mi=min(mi,n-i+u);
27 }
28 if(mi!=INF) ans[i]=n*(s[i].size()-1)+mi;
29 }
30 for(int i=1;i<=n;i++){
31 int res=0,time=n,k=i,cnt=0;
32 while(time--){
33 //注意
34 if(ans[k]!=0) res=max(res,ans[k]+cnt);
35 k++;
36 if(k==n+1) k=1;
37 cnt++;
38 }
39 printf("%d ",res);
40 }
41 return 0;
42 }
2019/3/2
CF 1130D2 Toy Train
和上题一样,改下long long就可以了,发现自己一开始写的就挺优的,O(n^2)。


1 #include <vector>
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7
8 const int N=5555;
9 typedef long long ll;
10 ll ans[N];
11 vector <int> s[N];
12
13 int main(){
14 int n,m;
15 scanf("%d%d",&n,&m);
16 for(int i=1;i<=m;i++){
17 int a,b;
18 scanf("%d%d",&a,&b);
19 s[a].push_back(b);
20 }
21 for(int i=1;i<=n;i++){
22 ll mi=1e18;
23 for(int j=0;j<s[i].size();j++){
24 int u=s[i][j];
25 if(u>=i) mi=min(mi,1LL*(u-i));
26 else mi=min(mi,1LL*(n-i+u));
27 }
28 if(mi!=1e18) ans[i]=1LL*n*(s[i].size()-1)+mi;
29 }
30 for(int i=1;i<=n;i++){
31 ll res=0;
32 int time=n,k=i,cnt=0;
33 while(time--){
34 if(ans[k]!=0) res=max(res,ans[k]+cnt);
35 k++;
36 if(k==n+1) k=1;
37 cnt++;
38 }
39 printf("%lld ",res);
40 }
41 return 0;
42 }
2019/3/3
CF 1114C Trailing Loves (or L'oeufs?)
b分解质因子,每个质因子对n!求指数,要使b全部符合,那么最少的那个指数就为答案。


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 typedef long long ll;
8 ll n,b,ans=1e18;
9
10 void cal(ll num,ll cnt){
11 ll tmp=1,res=0;
12 while(tmp<=n/num){
13 tmp*=num;
14 res+=n/tmp;
15 }
16 ans=min(ans,res/cnt);
17 }
18
19 int main(){
20 scanf("%lld%lld",&n,&b);
21 for(ll i=2;i*i<=b;i++){
22 if(b%i==0){
23 ll cnt=0;
24 while(b%i==0){
25 b/=i;
26 cnt++;
27 }
28 cal(i,cnt);
29 }
30 }
31 if(b>1) cal(b,1);
32 printf("%lld\n",ans);
33 return 0;
34 }
2019/3/4
CF 1114D Flood Fill(区间DP)
$dp[l][r][0]$表示以c[l]为整块颜色的最小花费,$dp[l][r][1]$表示以c[r]为整块颜色的最小花费。
转移方程:
$dp[l][r][0]=min(dp[l+1][r][0]+(c[l]!=c[l+1]),dp[l+1][r][1]+(c[l]!=c[r]))$
$dp[l][r][1]=min(dp[l][r-1][0]+(c[l]!=c[r]),dp[l][r-1][1]+(c[r-1]!=c[r]))$


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 const int N=5555;
8 int c[N],dp[N][N][2];
9
10 int main(){
11 memset(dp,0x3f,sizeof(dp));
12 int n;
13 scanf("%d",&n);
14 for(int i=1;i<=n;i++){
15 scanf("%d",&c[i]);
16 dp[i][i][0]=dp[i][i][1]=0;
17 }
18 for(int len=2;len<=n;len++){
19 for(int l=1;l<=n;l++){
20 int r=l+len-1;
21 if(r>n) break;
22 dp[l][r][0]=min(dp[l+1][r][0]+(c[l]!=c[l+1]),dp[l+1][r][1]+(c[l]!=c[r]));
23 dp[l][r][1]=min(dp[l][r-1][0]+(c[l]!=c[r]),dp[l][r-1][1]+(c[r-1]!=c[r]));
24 }
25 }
26 printf("%d\n",min(dp[1][n][0],dp[1][n][1]));
27 return 0;
28 }
2019/3/5
CF 1111C Creative Snap
DFS二分区间,比较继续二分后的代价和当前代价大小。区间长度问题可以二分区间。整体就是二分套二分啦。


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 const int N = 1e5 + 10;
8 int n, k, A, B;
9 int a[N];
10 typedef long long ll;
11
12 ll dfs(int l, int r){
13 int len = upper_bound(a + 1, a + 1 + k, r) - upper_bound(a + 1, a + 1 + k, l - 1 );
14 ll res = 0;
15 if(len) {
16 res = 1LL * B * len * (r - l + 1);
17 } else {
18 return A;
19 }
20 if(l == r) return res;
21 int mid = (l + r) / 2;
22 res = min(res, dfs(l, mid) + dfs(mid + 1, r));
23 return res;
24 }
25
26 int main() {
27 scanf("%d %d %d %d", &n, &k, &A, &B);
28 for(int i = 1; i <= k; i++) {
29 scanf("%d", &a[i]);
30 }
31 sort(a + 1, a + 1 + k);
32 printf("%lld\n", dfs(1, (1<<n) ));
33 return 0;
34 }
2019/3/6
CF 1111B Average Superhero Gang Power
排序后,从后往前累加,在当前数之前的数都删掉,剩下来的m给当前和之后的数平均分下去,如果平均分下去大于k,那就只给k,否则就可以全部分下去,更新下答案。


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 typedef long long ll;
8 const int N = 1e5 + 10;
9 ll a[N];
10
11 int main() {
12 double ans = 0;
13 int n, k, m;
14 scanf("%d %d %d", &n, &k, &m);
15 for(int i = 1; i <= n; i++) {
16 scanf("%lld", &a[i]);
17 }
18 sort(a + 1, a + 1 + n);
19 ll sum = 0;
20 for(int i = n; i >= 1; i--) {
21 sum += a[i];
22 if(m >= i - 1 ) {
23 int new_m = m - i + 1;
24 int ave = new_m / (n - i + 1);
25 if(ave >= k) {
26 ans = max(ans, 1.0 * sum / (n - i + 1) + 1.0 * k);
27 } else {
28 ans = max(ans, (1.0 * sum + 1.0 * new_m) / (n - i + 1) );
29 }
30 }
31 }
32 printf("%.10f", ans);
33 return 0;
34 }
2019/3/7
CF 1132 Painting the Fence
先枚举下第一个人画的区间,处理完后把第二个人画的区间用前缀处理下。最后遍历下所有人,更新答案。


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 const int N = 5555;
8 int p[N], l[N], r[N], cnt[N];
9
10 int main() {
11 int n, q, ans = 0, res = 0;
12 scanf("%d %d", &n, &q);
13 for(int i = 1; i <= q; i++) {
14 scanf("%d %d", &l[i], &r[i]);
15 for(int j = l[i]; j <= r[i]; j++) {
16 p[j]++;
17 if(p[j] == 1) ans++;
18 }
19 }
20 for(int i = 1; i <= q; i++) {
21 int sum = ans;
22 for(int k = l[i]; k <= r[i]; k++) {
23 p[k]--;
24 if(p[k] == 0) sum--;
25 }
26 for(int k = 1; k <= n; k++) {
27 if(p[k] == 1) cnt[k] = 1;
28 else cnt[k] = 0;
29 cnt[k] += cnt[k-1];
30 }
31 for(int k = i + 1; k <= q; k++) {
32 res = max(res, sum - (cnt[ r[k] ] - cnt[ l[k] - 1 ]));
33 }
34 for(int k = l[i]; k <= r[i]; k++) {
35 p[k]++;
36 }
37 }
38 printf("%d", res);
39 return 0;
40 }
2019/3/8
CF 1107D Compression
先暴力枚举出原来的n x n矩阵,然后对能整除n的数字进行判断,每一块负责的是否符合要求。更新最大的答案。(矩阵压缩)


1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 using namespace std;
6
7 const int N = 6666;
8 typedef long long ll;
9 int n, ans = 0;
10 string str, s[N];
11
12 string cal(char ch) {
13 if(ch == '0') return "0000";
14 if(ch == '1') return "0001";
15 if(ch == '2') return "0010";
16 if(ch == '3') return "0011";
17 if(ch == '4') return "0100";
18 if(ch == '5') return "0101";
19 if(ch == '6') return "0110";
20 if(ch == '7') return "0111";
21 if(ch == '8') return "1000";
22 if(ch == '9') return "1001";
23 if(ch == 'A') return "1010";
24 if(ch == 'B') return "1011";
25 if(ch == 'C') return "1100";
26 if(ch == 'D') return "1101";
27 if(ch == 'E') return "1110";
28 if(ch == 'F') return "1111";
29 }
30
31 bool check(int k) {
32 for(int x = 0; x < n; x+=k) {
33 for(int y = 0; y < n; y+=k) {
34 char ch = s[x][y];
35 for(int i = x; i < x + k; i++) {
36 for(int j = y; j < y + k; j++) {
37 if(s[i][j] != ch) return false;
38 }
39 }
40 }
41 }
42 return true;
43 }
44
45 int main() {
46 ios::sync_with_stdio(false);
47 cin >> n;
48 for(int i = 0; i < n; i++) {
49 cin >> str;
50 for(int j = 0; j < str.size(); j++) {
51 s[i] = s[i] + cal(str[j]);
52 }
53 }
54 for(int i = 1; i <= n; i++) {
55 if(n % i == 0) {
56 if(check(i)) ans = i;
57 }
58 }
59 cout << ans << endl;
60 return 0;
61 }
2019/3/9
CF 1133F1 Spanning Tree with Maximum Degree
从度数最大的点BFS一下即可。


1 #include <queue>
2 #include <vector>
3 #include <cstdio>
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7
8 const int N = 2e5 + 10;
9 int n, m;
10 int d[N];
11 bool vis[N];
12 vector<int> E[N];
13
14 void bfs(int st) {
15 queue<int> Q;
16 Q.push(st);
17 vis[st] = 1;
18 while(!Q.empty()) {
19 int u = Q.front();
20 Q.pop();
21 for(int i = 0; i < E[u].size(); i++) {
22 int v = E[u][i];
23 if(!vis[v]) {
24 printf("%d %d\n", u, v);
25 vis[v] = 1;
26 Q.push(v);
27 }
28 }
29 }
30 }
31
32 int main() {
33 scanf("%d %d", &n, &m);
34 for(int i = 1; i <= m; i++) {
35 int u, v;
36 scanf("%d %d", &u, &v);
37 E[u].push_back(v);
38 E[v].push_back(u);
39 d[u]++;d[v]++;
40 }
41 int mx = 0, id = 0;
42 for(int i = 1; i <= n; i++) {
43 if(d[i] > mx) {
44 mx = d[i];
45 id = i;
46 }
47 }
48 bfs(id);
49 return 0;
50 }
2019/3/10
CF 1137A Skyscrapers
离散化。


1 #include <queue>
2 #include <vector>
3 #include <cstdio>
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7
8 const int N = 1234;
9 int a[N][N];
10 vector<int> r[N],c[N];
11
12 int main() {
13 int n, m;
14 scanf("%d %d", &n, &m);
15 for(int i = 0; i < n; i++) {
16 for(int j = 0; j < m; j++) {
17 scanf("%d", &a[i][j]);
18 r[i].push_back(a[i][j]);
19 c[j].push_back(a[i][j]);
20 }
21 }
22 for(int i = 0; i < n; i++) {
23 sort(r[i].begin(), r[i].end());
24 r[i].erase(unique(r[i].begin(), r[i].end()), r[i].end());
25 }
26 for(int i = 0; i < m; i++) {
27 sort(c[i].begin(), c[i].end());
28 c[i].erase(unique(c[i].begin(), c[i].end()), c[i].end());
29 }
30 for(int i = 0; i < n; i++) {
31 for(int j = 0; j < m; j++) {
32 int p1 = lower_bound(r[i].begin(), r[i].end(), a[i][j]) - r[i].begin();
33 int p2 = lower_bound(c[j].begin(), c[j].end(), a[i][j]) - c[j].begin();
34 int p3 = r[i].end() - lower_bound(r[i].begin(), r[i].end(), a[i][j]);
35 int p4 = c[j].end() - lower_bound(c[j].begin(), c[j].end(), a[i][j]);
36 printf("%d", max(p1, p2) + max(p3, p4));
37 if(j == m - 1) printf("\n");
38 else printf(" ");
39 }
40 }
41 return 0;
42 }
来源:oschina
链接:https://my.oschina.net/u/4269622/blog/3647325