USACO专题题解

来源:

Section 1.2

Section 1.3

1.方块转换

思路:这道题的7种情况,我们可以把原图存在s1,把目标存在s2里面,然后各方法遍历如下:

1:先行从n到1变化,列从1到n变化
2:先列从n到1变化,行从n到1变化
3:先列从1到n变化,行从n到1变化
4:先列从n到1变化,行从1到n变化
5:先把每行进行逆序,然后执行1或2或3
6:把s1和s2比较是否相等
7:以上均不满足
然后把遍历的结果存入s3中,每次使用后清零,比较是否相等(当然6、7不要判断)

代码

#include <bits/stdc++.h>
using namespace std;
int n,i,j;
char a[11][11],b[11][11];
string s1,s2,s3="";
int main(){
    
    
	ios::sync_with_stdio(false);
	cin>>n;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++){
    
    
			cin>>a[i][j];
			s1+=a[i][j];	
		}
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++){
    
    
			cin>>b[i][j];
			s2+=b[i][j];	
		}
	for(i=1;i<=n;i++)
		for(j=n;j>=1;j--)s3+=a[j][i];
	if(s3==s2){
    
    
		cout<<1;
		return 0;	
	}
	s3="";
	for(i=n;i>=1;i--)
		for(j=n;j>=1;j--)s3+=a[i][j];
	if(s3==s2){
    
    
		cout<<2;
		return 0;	
	}
	s3="";
	for(i=n;i>=1;i--)
		for(j=1;j<=n;j++)s3+=a[j][i];
	if(s3==s2){
    
    
		cout<<3;
		return 0;	
	}
	s3="";
	for(i=1;i<=n;i++)
		for(j=n;j>=1;j--)s3+=a[i][j];
	if(s3==s2){
    
    
		cout<<4;
		return 0;
	}
	s3="";
	for(i=1;i<=n;i++)
		for(j=1;j<=n/2;j++)swap(a[i][j],a[i][n-j+1]);
	for(i=1;i<=n;i++)
		for(j=n;j>=1;j--)s3+=a[j][i];
	if(s3==s2){
    
    
		cout<<5;
		return 0;	
	}
	s3="";
	for(i=n;i>=1;i--)
		for(j=n;j>=1;j--)s3+=a[i][j];
	if(s3==s2){
    
    
		cout<<5;
		return 0;	
	}
	s3="";
	for(i=n;i>=1;i--)
		for(j=1;j<=n;j++)s3+=a[j][i];
	if(s3==s2){
    
    
		cout<<5;
		return 0;	
	}
	if(s1==s2)cout<<6;
	else cout<<7;
}
    

2.命名那个数字*

思路:我们可以建一个char数组,这样可以把手机按键模拟出来,然后用map来存这个数是否出现,接着进行深搜,然后如果字典中有这个名字就输出,然后做个标记,接着如果标记为0就输出“NOME”。
代码

#include <bits/stdc++.h>
using namespace std;
string a,x,s;
char ch[100][100]={
    
    "ABC","DEF","GHI","JKL","MNO","PRS","TUV","WXY"};
int l;
map<string,int>mp;
bool f;
void work(int deep){
    
    
    if(deep==l){
    
    
    	if(mp[s]==true){
    
    
    		for(int i=0;i<=l-1;i++)cout<<s[i];
    		cout<<endl;
			f=1;
		}
		return;
	}
	string t = s;
    for(int i=1;i<=3;i++){
    
    
    	s += ch[a[deep]-'0'-2][i-1];
    	work(deep+1);
    	s=t;
	}
	return;
}
int main() {
    
    
    ios::sync_with_stdio(false);
    cin>>a;
    l=a.size();
    for(int i=1;i<=4617;i++){
    
    
    	cin>>x;
    	mp[x]=true;
	}
    work(0);
    if(!f)cout<<"NONE";
}

3.回文平方数

思路:枚举[1,300],并建两个数组,分别表示原数的b进制和b之平方,每次让函数对数组更改,如果平方是回文,那么把原数的b进制算出输出(如果出现b>10,就在输出是判断改为是否>=10,再转成大写字母)。
代码

4.双重回文数

思路:直接搞个循环枚举进制,然后把每一位求出判断回文数是否>=2,输出即可。
代码

5.混合牛奶

思路:直接建结构体,然后对单价排序,然后取n和单价对应最大数量取最小值(因为这种牛奶只能供应这么多,并且我们也希望达到规定数量就可以了,这样省钱),减去两者最小后,再把单价*数量加入s,最后输出。

6.修理牛棚

思路:对牛所在的位置排序,然后像数列分段一样把牛分成若干段(即连续的牛算1段),然后每相邻两段距离求出,排序,再把前(我们分成的段数(即木板数)-目标木板数)的个数加进去(如<=0则不加)。

7.滑雪课程设计

思路:我们可以枚举最低高度(0~87),然后最高高度可以是最低高度+17,所以高于最低高度超过17我们就需要进行减小,如果比最低高度小我们就要增高。
代码

#include<bits/stdc++.h>
using namespace std;
int n,a[10001],s,minn=INT_MAX,i,j;
int main(){
    
    
	cin>>n;
	for(i=1;i<=n;i++)cin>>a[i];
	for(i=0;i<=83;i++){
    
    
		s=0;
		for(j=1;j<=n;j++){
    
    
			if(a[j]<i)s+=(i-a[j])*(i-a[j]);
			if(a[j]>i+17)s+=(a[j]-i-17)*(a[j]-i-17);
		}
		minn=min(s,minn);
	}
	cout<<minn;
}

猜你喜欢

转载自blog.csdn.net/weixin_52536621/article/details/113571697