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;
}