11.15
洛谷题没有写过很多
问题也不多;主要是狂补了学校oj的USACO题
题目质量都挺高,都值得记录
USACO Training 1.1.4 Broken Necklace
这题开始的想法就是先遍历剪切点 然后往两边开始比较直到遇到不是w或者非异色的珠子;
开始是想把开头结尾作为一个间断点;然后把第一个抛到后面;整体前移;就又有了一个间断点;从头尾分别计数;
这样显得有点麻烦;后来还是把两串珠子首尾连接;比如bbrwrr;就可以变成bbrwrrbbrwrr;那这样不是只要用下标就可以考虑进环形的问题了吗?
然后考虑计数问题;开始就单纯的想前一位与后一位比较;但在只有确定颜色的情况下才适用;但在w存在的情况下,就不行了;如在bbwrr;它会计数为5;后来就想到首先来一个粗遍历,记下第一个非w的字符;按照他去校验;
最后有一个问题,就是当为单色时;如bbbwb,rrwrwr;它会计数为2n;应当特判;
code:
#include <iostream>
#include<string>
using namespace std;
int main()
{
int n;cin>>n;
string zh;char t;
for(int i=0;i<n;i++)
{
char x;cin>>x;
zh.push_back(x);
}
zh+=zh;int m=0,ans=0;
for(int i=0;i<=2*n;i++)
{
for(int j=i;j<2*n;j++)
{
if(zh[j]!='w')
{
t=zh[j];break;
}
}
for(int j=i;j<2*n;j++)
{
if(zh[j]==t||zh[j]=='w')ans++;
else break;
}
for(int j=i-1;j>=0;j--)
{
if(zh[j]!='w')
{
t=zh[j];break;
}
}
for(int j=i-1;j>=0;j--)
{
if(zh[j]==t||zh[j]=='w')ans++;
else break;
}
if(m<ans&&ans<n)m=ans;
else if(ans>=n)
{
m=n;break;
}
ans=0;
}
cout<<m<<endl;
return 0;
}
USACO Training 1.2.2 Transformations
这题也算容易了;就是转90°的规律找了很久;
其他倒没什么问题;
只是后面的if嵌套有点麻烦;多谢cy学长的指出;
code:
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
char a[20][20],b[20][20],c[20][20],d[20][20];int n;
bool cz1()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
c[j][n-i+1]=a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(c[i][j]!=b[i][j])return 0;
}
}
return 1;
}
bool p1()
{
char t;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
d[j][n-i+1]=c[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(d[i][j]!=b[i][j])return 0;
}
}
return 1;
}
bool p2()
{
char t;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
c[j][n-i+1]=d[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(c[i][j]!=b[i][j])return 0;
}
}
return 1;
}
bool cz2()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
c[i][n-j+1]=a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(c[i][j]!=b[i][j])return 0;
}
}
return 1;
}
bool cz3()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]!=b[i][j])return 0;
}
}
return 1;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>b[i][j];
}
}
if(cz1())cout<<1;
else if(p1())cout<<2;
else if(p2())cout<<3;
else if(cz2())cout<<4;
else if(!cz2())
{
cz2();
if(p1())cout<<5;
else if(p2())cout<<5;
else if(p1())cout<<5;
else if(cz3())cout<<6;
else if(!cz3())cout<<7;
}
return 0;
}
USACO Training 1.2.4 Palindromic Squares
多种进制下的回文数;一般都是用倒取余数法;但是10进制以上是带字母的
就应该开一个字符串作为存余数的容器;判断函数就应该是常规了;
bool jg(int x,int y)
{
char jinzhi[50]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char s[200];
int i=0,j;
while(x)
{
s[i]=jinzhi[x%y];
x/=y;
i++;
}
for(j=0;j<i-j-1;j++)
{
if(s[j]!=s[i-j-1])
return 0;
}
return 1;
}
遍历也没问题;就是输出有点毛病;它是要按进制输出的;回文数没什么;
倒取余数就行;反正首位一样;但原数就有点麻烦;我就直接用了string库的insert函数
string p1(int x,int y)
{
string jinzhi="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string s;
int i=0;
while(x)
{
s.push_back(jinzhi[x%y]);
x/=y;
i++;
}
return s;
}
string p2(int x,int y)
{
string jinzhi="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string s;
int i=0;
while(x)
{
s.insert(0,1,jinzhi[x%y]);
x/=y;
i++;
}
return s;
}
这是变进制的函数;
int main()
{
int a;cin>>a;
for(int i=1;i<=300;i++)
{
if(jg(i*i,a))
{
cout<<p2(i,a)<<' '<<p1(i*i,a)<<endl;
}
}
return 0;
}
主函数;
USACO Training 1.3.4 Prime Cryptarithm
这题乍一看很难;但实际上是一道暴力至死的题;
有些人开了5个嵌套循环;但我觉得没必要;
#include <iostream>
#include <algorithm>
using namespace std;
bool a[20];
bool jp(int x)
{
while(x!=0)
{
if(a[x%10]==0)return 0;
x/=10;
}
return 1;
}//判断是不是在集合内
bool t(int e)
{
if(e/1000!=0)return 0;
else return 1;
}//判断位数
bool tt(int r)
{
if(r/10000!=0)return 0;
else return 1;
}//判断位数
int main()
{
int a1,a2;
int b1,b2;int k=0;int g;
int n;cin>>n;
for(int i=1;i<=n;i++)
{
int t;cin>>t;
a[t]=1;
}
for(a1=11;a1<=99;a1++)
{
for(a2=111;a2<=999;a2++)
{
b1=(a1%10)*a2;
b2=(a1/10)*a2;
g=a1*a2;
if(jp(a1)&&jp(a2)&&jp(b1)&&jp(b2)&&jp(g)&&t(b1)&&t(b2)&&tt(g))
//这句if看着我自己都怕;
k++;
}
}
cout<<k;
return 0;
}
liule;