2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 2)(蒟蒻解题)(全部都是水题和思维题)

2018.5.14:还有三个没有补,一个然颜色种类那个,一个求fn的,一个尺取能写的题(估计是个简单dp)
http://codeforces.com/gym/101652
A problemN
给定一个字符串,问你判断该字符串的所有回文字串(注意单词consective,连续,故是回文子串)的长度是否都是奇数串,若是就输出Odd. 否则输出 Or not.


思路:如果存在回文字串为偶数的话,一定会有两个相同的字母相同,我们把这两个扣出来,就构成了一个偶数的回文串,所以只需要判断是否存在两个相邻的字母相同即可

#include <iostream>

using namespace std;

int main()
{    string s;
      while(cin>>s){
      bool flag=false;
      for(int i=0;i<s.length()-1&&!flag;i++){
          if(s[i]==s[i+1])flag=true;
      }
      if(flag)
         puts("Or not.");
     else
         puts("Odd.");
  }
    return 0;
}

B:problme O
给定一个矩阵,问你判断该矩阵每一行每一列的字母都个个不相同,且第一行和第一列的元素都是按照自然顺序排序的(从小到大)
若试,则输出Reduced
若满足第一个条件不满足第二个,输出Not reduced
若都不满足,输出NO


思路:模拟(错啦两遍枚举题意啦,自然顺序是下降,不一定只差1)

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
set<int>se;
char a[50][50];
int solve(char a,char b){
     int aa;
     int bb;
     if(a>='A'&&a<='Z')aa=(a-'A'+10);
     else if(a>='0'&&a<='9')aa=a-'0';
     if(b>='A'&&b<='Z')bb=(b-'A'+10);
     else if(b>='0'&&b<='9')bb=b-'0';
     return a-b;
}
int main()
{      int m;
      while(cin>>m){
           bool flag=false;
           for(int i=1;i<=m;i++){
              for(int j=1;j<=m;j++){
                 cin>>a[i][j];
                }
             }
             for(int i=1;i<=m;i++){
                 se.clear();
                 for(int j=1;j<=m;j++){
                    se.insert(a[i][j]);
                  }
                  if(se.size()<m){
                   flag=true;
                   }
             }
             for(int i=1;i<=m;i++){
                se.clear();
                for(int j=1;j<=m;j++){
                   se.insert(a[j][i]);
                }
                if(se.size()<m)
                flag=true;
             }
             if(flag){
               puts("No");
             }
             else{
                for(int i=2;i<=m;i++){
                   if(solve(a[1][i],a[1][i-1])<=0)
                    flag=true;
                }
                for(int j=2;j<=m;j++){
                   if(solve(a[j][1],a[j-1][1])<=0)
                   flag=true;
                }
                if(flag){
                  puts("Not Reduced");
                }
                else{
                  puts("Reduced");
                }

             }





      }



    return 0;
}

M:problemZ
不说啦,看代码就知道啥题意啦。。

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
bool check(int m){
     while(m){
        int ans=m%10;
        if(!ans)return true;
        m/=10;
     }
     return false;
}
int main()
{      int m;
        while(cin>>m){
             m++;
             while(check(m))m++;
             cout<<m<<endl;

        }



    return 0;
}

L:problemY
题意:已知x, k, p, 求x * n + k * p / n的最小值

思路:对号函数,因为n为整数,输出sqrt(k * p / x)左右两个整点对应函数值的最小值。O(1)。。
这显然是大佬的思路,我想三分来着,后来又觉得1e7试一下估计也行。就。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
using namespace std;
 int k, p, x;
double cal(int n) {
     return 1.0 * x * n + 1.0 * k * p / n;
 }
int main()
{





     scanf("%d%d%d", &k, &p, &x);
     int n = sqrt((k * p + 0.5) / x);//直接 结取的
     printf("%.3f\n", min(cal(n), cal(n + 1)));
     return 0;
    return 0;
}

暴力

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
void senfen(){

}
double k,p,x;
int main()
{     while(~scanf("%lf%lf%lf",&k,&p,&x)){
           double ans=1e9+7;
           for(int i=1;i<=1e7;i++){
                double s=x*i+(k*p)/(1.0*i);
               ans=min(ans,s);
           }
           printf("%.3f\n",ans);

     }



    return 0;
}

H:problem u
给一个筛子(die有筛子的意思),每面的概率如下(很明显是灌了水银的),然后你可以改变表面的值,使其期望为3.5,并要求改动的数字和原数差距最小。
思路:恩,排序就好啦

#include <iostream>
#include <cstdio>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
double a[6];
struct Node{
   double l;
   int r;
};
bool cmp2(Node a,Node b){
    return a.l>b.l;
}
int main()
{   Node a[6];
    double sum=0;
     for(int i=0;i<6;i++){
         cin>>a[i].l;
         sum+=a[i].l*(i+1);
         a[i].r=i;
     }
     sort(a,a+6,cmp2);
     //cout<<sum<<endl;
        //cout<<abs(sum-3.5)/a[0].l<<endl;
        //cout<<a[0].r*1.0<<endl;
        double tt=abs(sum-3.5)/a[0].l;
        printf("%.3f\n",tt);
    return 0;
}   

K:problemx
给定一些星星,以下规则
每隔一行数量相同。
第一行必须不等小于第二行
相邻行差值最大为1
问你有多少种合法的方案。。
思路:有点懵啊。。 后来发现就三种情况。
1 行行相等。
2 差值为1,总数奇数
2 差值为1,总数偶数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
using namespace std;
const int maxn=12;
set<pair<int,int> >q;
int main()
{   int s;
    while(cin>>s){
         q.clear();
         for(int i=2;i<s;i++){
             if(s%i==0)
               q.insert(make_pair(i,i));
         }
         for(int i=2;i<s;i++){
             if(s%(i+i-1)==0||((s-i)%(i+i-1)==0))
             q.insert(make_pair(i,i-1));
         }
         printf("%d:\n",s);
         set<pair<int,int> >::iterator it;
         for(it=q.begin();it!=q.end();it++){
            cout<<it->first<<","<<it->second<<endl;
         }
    }

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值