前言
开始刷USACO的题了。
正题
刷前必备技能:OI常识,bfs,dfs,位运算,基础贪心,快速排序。
T1:城堡 TheCastleThe CastleTheCastle
评测记录:
https://www.luogu.org/recordnew/lists?uid=52918&pid=P1457
之前写过,详见:
https://blog.csdn.net/Mr_wuyongcong/article/details/78937287
T2:顺序的分数 OrderedFractionsOrdered FractionsOrderedFractions
评测记录:https://www.luogu.org/problemnew/show/P1458
题目大意
求最简分数
ab(a,b<=n,a,b∈N)\frac{a}{b}(a,b<=n,a,b\in N)ba(a,b<=n,a,b∈N)
从小到大输出。
解题思路
暴力枚举ab,gcd判断最间,然后排序。
code
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
using namespace std;
int n,tot;
struct node{int a,b;double w;
}a[10001];
bool cmp(node x,node y)
{return x.w<y.w;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++)if(__gcd(i,j)==1) {a[++tot]=(node){i,j,(double)i/j};}//暴力枚举sort(a+1,a+1+tot,cmp);//排序printf("0/1\n");for(int i=1;i<=tot;i++)printf("%d/%d\n",a[i].a,a[i].b);printf("1/1");
}
T3:三值的排序 SortingaThree−ValuedSequenceSorting a Three-Valued SequenceSortingaThree−ValuedSequence
评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=P1459
题目大意
1,2,3构成的序列,要求至少多少次交换可以将其变为升序序列。
解题思路
我们考虑所以放错位置的数。
如果3放在了1,2的位置上,那么就一定是需要一次交换的。如果1放在了2的位置或2放在了1的位置,那么可以选择1放回去或2放回去,当然我们可以将错的2和错的1抵消所以答案就是
wrong3+max{wrong1,wrong2}wrong_3+max\{wrong_1,wrong_2\}wrong3+max{wrong1,wrong2}
code
#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[1001],s,num[4],fail[4];
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]),num[a[i]]++;for(int i=1;i<=num[1]+num[2];i++){if(a[i]==3) fail[3]++;//3放错位置if(i<=num[1]&&a[i]==2) fail[2]++;//2放错位置if(i>num[1]&&a[i]==1) fail[1]++;//1放错位置}printf("%d",fail[3]+max(fail[1],fail[2]));
}
T4:健康的荷斯坦奶牛 HealthyHolsteinsHealthy HolsteinsHealthyHolsteins
评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=P1460
题目大意
牛对于v种维生素有不同的需求,每包饲料含有不等量不同的维生素。求需要的最少饲料包数
解题思路
dfs暴搜
code
#include<cstdio>
using namespace std;
int v,n,mins,ans[30],h[30][30],use[30],ne[30],now[30];
bool check()
{for(int i=1;i<=v;i++)if(now[i]<ne[i]) return false;return true;
}
void dfs(int dep,int c)
{if(c>=mins||dep>n) return;if(check()){for(int i=1;i<=n;i++)ans[i]=use[i];mins=c;}use[dep+1]=1;for(int i=1;i<=v;i++)now[i]+=h[dep+1][i];dfs(dep+1,c+1);use[dep+1]=0;for(int i=1;i<=v;i++)now[i]-=h[dep+1][i];dfs(dep+1,c);
}
int main()
{scanf("%d",&v);for(int i=1;i<=v;i++)scanf("%d",&ne[i]);scanf("%d",&n);for(int i=1;i<=n;i++)for(int j=1;j<=v;j++)scanf("%d",&h[i][j]);mins=2147483647;dfs(0,0);printf("%d ",mins);for(int i=1;i<=n;i++)if(ans[i]) printf("%d ",i);
}
T5:海明码 HammingCodesHamming CodesHammingCodes
评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=P1461
题目大意
求n个最小的非负整数,要求每个数两两之间HammingHammingHamming距离(二进制位数不相同的个数)。
解题思路
之接暴力过去枚举数,然后a⨁ba\bigoplus ba⨁b后统计1的个数就可以计算距离来判断。
code
#include<cstdio>
#include<algorithm>
using namespace std;
int n,b,d,now,last,tot,ans[100];
int main()
{scanf("%d%d%d",&n,&b,&d);n--;tot=1;printf("0 ");ans[1]=0;while(n){now++;bool flag=true;for(int i=0;i<=tot;i++){if(__builtin_popcount(now^ans[i])<d){flag=false;break;}}//是否满足要求if (flag){printf("%d ",now);ans[++tot]=now;if(tot%10==0) printf("\n");n--;}}
}