Codeforces Round #533 (Div. 2)(ABCD)

痛定思痛。 2023-06-03 13:52 64阅读 0赞

A. Salem and Sticks(暴力)

题意:给你n个棒子,长度分别为ai,让你找到一个长度x,使得n个棒子的长度都变为x+1或者x-1或者x的花费最小,花费为abs(ai-b);

解:因为n只有1000,棒子最长也只有100;所以在1-100内暴力就行了;

ContractedBlock.gif ExpandedBlockStart.gif

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int maxn=1e5+10;
  5. const int inf=0x3f3f3f3f;
  6. int a[maxn];
  7. int b[maxn],n,c[maxn];
  8. int gao(int ans){
  9. int sum=0;
  10. for(int i=1;i<=n;i++){
  11. if(a[i]==ans+1||a[i]==ans||a[i]==ans-1)continue;
  12. sum+=abs(ans-a[i])-1;
  13. }
  14. return sum;
  15. }
  16. int main(){
  17. cin>>n;
  18. for(int i=1;i<=n;i++){
  19. cin>>a[i];
  20. }
  21. sort(a+1,a+1+n);
  22. int flag=0,sum1=0,sum2=0,sum3=0,minn=inf;
  23. for(int i=1;i<=n;i++){
  24. if(a[i]==a[i-1])
  25. continue;
  26. sum1=gao(a[i]);
  27. sum2=gao(a[i]-1);
  28. sum3=gao(a[i]+1);
  29. minn=min(minn,min(sum1,min(sum2,sum3)));
  30. if(minn==sum1){
  31. flag=a[i];
  32. }
  33. else if(minn==sum2){
  34. flag=a[i]-1;
  35. }
  36. else if(minn==sum3){
  37. flag=a[i]+1;
  38. }
  39. }
  40. cout<<flag<<' '<<minn<<endl;
  41. return 0;
  42. }

B. Zuhair and Strings

题意:给你一个字符串s,问你有多少个长度为k的连续相同的字符字串;

解:统计每个字母长度为k的字串用num记录,然后跑一遍num找出最大值;刚开始忘了处理结尾的字符导致wa了两罚;

ContractedBlock.gif ExpandedBlockStart.gif

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int maxn=2e5+10;
  5. const int inf=0x3f3f3f3f;
  6. int num[30];
  7. int main(){
  8. ios::sync_with_stdio(false);
  9. string s;
  10. int n,k;
  11. cin>>n>>k;
  12. cin>>s;
  13. int cnt=1;
  14. for(int i=1;i<n;i++){
  15. if(s[i]==s[i-1]){
  16. cnt++;
  17. }
  18. else{
  19. if(cnt/k)num[s[i-1]-'a']+=cnt/k;
  20. cnt=1;
  21. }
  22. }
  23. if(cnt/k)num[s[n-1]-'a']+=cnt/k;
  24. int ans=0;
  25. for(int i=0;i<26;i++){
  26. ans=max(ans,num[i]);
  27. }
  28. cout<<ans<<endl;
  29. return 0;
  30. }

C. Ayoub and Lost Array(DP)

题意:问区间[L,R]内n个数之和%3==0有多少组,数字可以重复使用;

解:刚开始想用多重集排列来做,先求出总的,然后再减去%3==1 %3==2的个数,算了半天发现走不通;

然后观摩了别人的做法,dp

先算一下L-R内%3分别等于0,1,2的个数

用前缀的思想,L-R内%3==0的有R/3-(L-1)/3;那么1和2分别就是(R+2)/3-(L+1)/3 (R+1)/3-(L)/3 (这个可以用a%3=0然后再推一下)

dp[i][0,1,2] i表示选择 i 个时的情况%3==0/1/2的分别有几种

然后dp[i][0]=dp[i-1][0]*a+dp[i-1][1]*c+dp[i-1][2]*b;

其他两个也跟上面差不多;

ContractedBlock.gif ExpandedBlockStart.gif

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=2e5+10;
  4. const int mod=1e9+7;
  5. typedef long long ll;
  6. ll dp[maxn][3];
  7. int main(){
  8. ll n,l,r;
  9. cin>>n>>l>>r;
  10. ll a=r/3-(l-1)/3;
  11. ll b=(r+2)/3-(l+1)/3;
  12. ll c=(r+1)/3-l/3;
  13. dp[1][0]=a,dp[1][1]=b,dp[1][2]=c;
  14. for(int i=2;i<=n;i++){
  15. dp[i][0]=(dp[i-1][0]*a%mod+dp[i-1][1]*c%mod+dp[i-1][2]*b%mod)%mod;
  16. dp[i][1]=(dp[i-1][1]*a%mod+dp[i-1][0]*b%mod+dp[i-1][2]*c%mod)%mod;
  17. dp[i][2]=(dp[i-1][2]*a%mod+dp[i-1][0]*c%mod+dp[i-1][1]*b%mod)%mod;
  18. }
  19. cout<<dp[n][0]%mod<<endl;
  20. return 0;
  21. }

D. Kilani and the Game(感觉比c简单)(BFS)

题意:给你n*m的图,有p个人,每个人的扩展速度为si,然后#不能扩展,每轮每个人只能扩展一次,直到扩展到不能扩展为止,问每个人的领域是多少

解:每轮每个人跑si次BFS,每次跑完的点再用一个queue来存,然后跑完当前所有的,再把暂存的放到原本的队列中

没做到完美的剪枝导致T了2发;

ContractedBlock.gif ExpandedBlockStart.gif

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int maxn=1e3+10;
  5. int n,m,p;
  6. char s[maxn];
  7. ll ans[maxn];
  8. bool vis[maxn][maxn];
  9. ll sp[maxn];
  10. int cnt=0;
  11. int dx[4]={
  12. 0,1,-1,0};
  13. int dy[4]={
  14. 1,0,0,-1};
  15. queue<pair<int,int>>que[maxn],t;
  16. void bfs(int st){
  17. int o=sp[st];
  18. int tot=0;
  19. while(tot<o){
  20. int xx=cnt;
  21. while(!que[st].empty()){
  22. pair<int,int>u=que[st].front();que[st].pop();
  23. int x=u.first;
  24. int y=u.second;
  25. for(int i=0;i<4;i++){
  26. int nx=x+dx[i];
  27. int ny=y+dy[i];
  28. if(nx<0||ny<0||nx>=n||ny>=m||vis[nx][ny])continue;
  29. vis[nx][ny]=true;
  30. t.push(make_pair(nx,ny));
  31. ans[st]++;
  32. cnt++;
  33. }
  34. }
  35. if(xx==cnt)return;//剪枝(这个很重要)
  36. if(cnt>=n*m)return;
  37. while(!t.empty()){
  38. pair<int,int>u=t.front();
  39. t.pop();
  40. que[st].push(u);
  41. }
  42. tot++;
  43. if(o==tot)return;
  44. }
  45. }
  46. int main(){
  47. ios::sync_with_stdio(false);
  48. cin>>n>>m>>p;
  49. for(int i=1;i<=p;i++){
  50. cin>>sp[i];
  51. }
  52. for(int i=0;i<n;i++){
  53. cin>>s;
  54. for(int j=0;j<m;j++){
  55. if(s[j]=='#'){
  56. vis[i][j]=true;
  57. cnt++;
  58. }
  59. else if(s[j]>='0'&&s[j]<='9'){
  60. vis[i][j]=true;
  61. ans[s[j]-'0']++;
  62. que[s[j]-'0'].push(make_pair(i,j));
  63. cnt++;
  64. }
  65. }
  66. }
  67. while(cnt<n*m){
  68. int xx=cnt;
  69. for(int i=1;i<=p;i++){
  70. bfs(i);
  71. }
  72. if(cnt==xx)break;//剪枝
  73. }
  74. for(int i=1;i<=p;i++){
  75. cout<<ans[i]<<' ';
  76. }
  77. cout<<endl;
  78. return 0;
  79. }

转载于:https://www.cnblogs.com/lin1874/p/11371003.html

发表评论

表情:
评论列表 (有 0 条评论,64人围观)

还没有评论,来说两句吧...

相关阅读