又回到最初的起点……
而我仍是如此蒟蒻。
噗那就一步一步慢慢来吧不着急2333。
T1:模拟题,小心一个是不要枚举成1到n了,一个是写存在继续操作写习惯了,忘了打非符号。
记得昨年考的时候有个等号少写了检查了很久哈哈哈。
#include<iostream>
#include<cstdio>
using namespace std;
int n,ans[50][50];
int main()
{
freopen("magic.in","r",stdin);
freopen("magic.out","w",stdout);
scanf("%d",&n);
ans[1][(n+1)/2]=1;
for(int i=2;i<=n*n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
if(ans[j][k]==i-1){
if(j==1&&k==n){
ans[j+1][k]=i;
}
else if(j==1){
ans[n][k+1]=i;
}
else if(k==n){
ans[j-1][1]=i;
}
else{
if(!ans[j-1][k+1])ans[j-1][k+1]=i;
else ans[j+1][k]=i;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)printf("%d ",ans[i][j]);
printf("\n");
}
return 0;
}
T2:
题意:每次从每点同时向其父节点自己已有传输信息(每点有且仅有一父节点),求多久后传到自己这里。
分析:记得当时拿的模拟分hhh.
分析一下就知道拿到自己的要在环上,所以要求最小环。
然而n三方,所以继续找没用到的特点,嗯n点n边,只要找到强连通分量就不可能一个套另一个强连通分量(不然边不够)
所以写了个诡异的dfs,思路还是tarjan.
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=2e5+5;
int mini=2e9,n,tov[maxn],dep[maxn],used[maxn];
int dfs(int u,int ste)
{
dep[u]=ste;
if(!used[tov[u]]) {
if(dep[tov[u]]){
used[u]=1;
return dep[u]-dep[tov[u]]+1;
}
int ans=dfs(tov[u],ste+1);
used[u]=1;
return ans;
}
used[u]=1;
return (int)2e9;
}
int main()
{
freopen("message.in","r",stdin);
freopen("message.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&tov[i]);
for(int i=1;i<=n;i++)if(!used[i])
mini=min(mini,dfs(i,1));
printf("%d",mini);
return 0;
}
T3:做到这里还有两个小时(一共考3h),但我,没有胆量花时间去分析,上手就暴力,最后发现好像大家分都高得吓人,这里要反思、要静下心来分析,平时考试分数不是最重要的,而且也看得出来这是简单题,划线又不按照分数划。
题意:给定一副牌,有不同的走牌方式,求怎样最快走完。
分析:(我觉得它的思路是把不能贪心的地方先枚举,剩下的贪心,不过出题人想的应该是map记忆化搜索不然不会给这么大内存。
然后就是直接分析贪心会发现不能贪心,仔细观察发现基本上问题都出现在顺子上,先把顺子给枚举了,剩下的地方就可以贪心了。
这种方法没用过,挺巧妙的。)
5min后补充:上述方法实力打脸,随机数据给了贪心太多施展自己力量的空间然后这个贪心是错的。
包括day1AK了的两位大神,跑出来的答案,都是错的。
幸好我记得去证明QAQ
下面的程序是错的QAQ
#include<iostream>
#include<cstdio>
#include<cstring>
#define clr(x) memset(x,0,sizeof(x))
using namespace std;
int n,t,cur[30],num,col,mini,tot[5];
int calc()
{
clr(tot);int ret=0;
for(int i=0;i<=14;i++)tot[cur[i]]++;
while(tot[4]&&tot[2]>=2){
ret++;tot[4]--;tot[2]-=2;
}
while(tot[4]&&tot[1]>=2){
ret++;tot[4]--;tot[1]-=2;
}
while(tot[3]&&tot[2]){
ret++;tot[3]--;tot[2]--;
}
while(tot[3]&&tot[1]){
ret++;tot[3]--;tot[1]--;
}
if(cur[1]&&cur[0]&&tot[1]>=2)tot[1]--;
return ret+tot[4]+tot[3]+tot[2]+tot[1];
}
void dfs(int ste)
{
if(ste>mini)return;
mini=min(mini,ste+calc());
for(int i=3;i<=13;i++)if(cur[i]>=3){
cur[i]-=3;int j=i+1;
for(j=i+1;j<=14;j++)if(cur[j]<3)break;
else {
cur[j]-=3;
dfs(ste+1);
}
for(int k=i;k<j;k++)cur[k]+=3;
}
for(int i=3;i<=12;i++)if(cur[i]>=2){
cur[i]-=2;int j=i+1;
for(j=i+1;j<=14;j++)if(cur[j]<2)break;
else {
cur[j]-=2;
if(j-i>=2)dfs(ste+1);
}
for(int k=i;k<j;k++)cur[k]+=2;
}
for(int i=3;i<=10;i++)if(cur[i]){
cur[i]--;int j=i+1;
for(j=i+1;j<=14;j++)if(!cur[j])break;
else {
cur[j]--;
if(j-i>=4)dfs(ste+1);
}
for(int k=i;k<j;k++)cur[k]++;
}
}
int main()
{
freopen("landlords.in","r",stdin);
freopen("landlords.out","w",stdout);
scanf("%d %d",&t,&n);
for(int i=1;i<=t;i++){
clr(cur);mini=2e9;
for(int i=1;i<=n;i++){
scanf("%d %d",&num,&col);
if(num>=2)cur[num]++;
else if(num==1)cur[14]++;
else if(col==1)cur[0]++;
else cur[1]++;
}
dfs(0);
printf("%d\n",mini);
}
return 0;
}
我马上写个正确的,我错了QWQ
#include<iostream>
#include<cstdio>
#include<cstring>
#define clr(x) memset(x,0,sizeof(x))
using namespace std;
int n,t,cur[30],num,col,mini;
int calc()
{
int ret=0;
for(int i=0;i<=14;i++)if(cur[i])ret++;
if(cur[0]&&cur[1])ret--;
return ret;
}
void dfs(int ste)
{
if(ste>mini)return;
mini=min(mini,ste+calc());
for(int i=3;i<=13;i++)if(cur[i]>=3){
cur[i]-=3;int j=i+1;
for(j=i+1;j<=14;j++)if(cur[j]<3)break;
else {
cur[j]-=3;
dfs(ste+1);
}
for(int k=i;k<j;k++)cur[k]+=3;
}
for(int i=3;i<=12;i++)if(cur[i]>=2){
cur[i]-=2;int j=i+1;
for(j=i+1;j<=14;j++)if(cur[j]<2)break;
else {
cur[j]-=2;
if(j-i>=2)dfs(ste+1);
}
for(int k=i;k<j;k++)cur[k]+=2;
}
for(int i=3;i<=10;i++)if(cur[i]){
cur[i]--;int j=i+1;
for(j=i+1;j<=14;j++)if(!cur[j])break;
else {
cur[j]--;
if(j-i>=4)dfs(ste+1);
}
for(int k=i;k<j;k++)cur[k]++;
}
for(int i=2;i<=14;i++)if(cur[i]>=4){
cur[i]-=4;
for(int j=2;j<=14;j++)if(cur[j]>=2){
cur[j]-=2;
for(int k=2;k<=14;k++)if(cur[k]>=2){
cur[k]-=2;
dfs(ste+1);
cur[k]+=2;
}
cur[j]+=2;
}
cur[i]+=4;
}
for(int i=2;i<=14;i++)if(cur[i]>=4){
cur[i]-=4;
for(int j=0;j<=14;j++)if(cur[j]){
cur[j]--;
for(int k=0;k<=14;k++)if(cur[k]){
cur[k]--;
dfs(ste+1);
cur[k]++;
}
cur[j]++;
}
cur[i]+=4;
}
for(int i=2;i<=14;i++)if(cur[i]>=3){
cur[i]-=3;
for(int j=2;j<=14;j++)if(cur[j]>=2){
cur[j]-=2;
dfs(ste+1);
cur[j]+=2;
}
cur[i]+=3;
}
for(int i=2;i<=14;i++)if(cur[i]>=3){
cur[i]-=3;
for(int j=0;j<=14;j++)if(cur[j]){
cur[j]--;
dfs(ste+1);
cur[j]++;
}
cur[i]+=3;
}
}
int main()
{
freopen("landlords.in","r",stdin);
freopen("landlords.out","w",stdout);
scanf("%d %d",&t,&n);
for(int i=1;i<=t;i++){
clr(cur);mini=2e9;
for(int i=1;i<=n;i++){
scanf("%d %d",&num,&col);
if(num>=2)cur[num]++;
else if(num==1)cur[14]++;
else if(col==1)cur[0]++;
else cur[1]++;
}
dfs(0);
printf("%d\n",mini);
}
return 0;
}
这个是对的……然后这是YJQ大神的剪枝,其实就是贪心,因为能带就带上肯定不会出问题!而且没带的也都枚举了,其实只是省去了由于排序出现的重复计算以及很多不必要的计算(比如上界的计算,就不用去跑了,直接递推);(顺序问题的精简很重要!)
CSZ做的是DP,存了四维,然后针对不同情况来计算,只需要搜顺子就可以了(因为只在顺子里数码会有影响),我觉得这个就是我上面被打脸了的那个“排除不能被贪心的因素”对应的“排除一些元素让DP好表示”;