cf B. Brand New Easy Problem
2016-03-10 11:31
190 查看
给你一组n个字串,然后再给出k组字符串,每组含有mi个。。
然后用n个子串去匹配k组字符串,求最小的逆序对。。。
在匹配k组字符串时出现问题,因为k组字符串中的单词会重复,所以不知怎么去取舍,我是用贪心的方法如果两个单词相等,则比较相邻两个单词,如果前一个单词比后面一个单词大,则删掉,事实这种方法不对,然而我想不到逆向思维,就是利用next_permutation(),求出每个下一个排列中的逆序对,然后再去匹配k组字符串,由于下一个排列中的逆序对是递增的,而且数据小,所以可以很快得出,但是注意一点(刚开始没注意,后来去查数据,唉~~我知道查数据这种方式不太对,但是我感觉自己想不出原因,所以重视忍不住去查数据,这种学习方法已经很多年了,我知道不好,但是不知怎么去改;额),当两个排列的逆序对相等时,要求出的是最小序号,所以每一个排列都要检索。。。。
代码写的很挫~~~感觉还不如大一的人~~~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m,k,a[20];
struct node
{
int s[30];
int mount;
} p[20];
char sr[20][25];
int nixudui()
{
int cnt=0;
for(int i=1; i<=n; i++)
{
for(int j=i+1; j<=n; j++)
{
if(a[i]>a[j])
cnt++;
}
}
return cnt;
}
int main()
{
cin>>n;
char l[30];
for(int i=1; i<=n; i++)
{
cin>>sr[i];
a[i]=i;
}
cin>>k;
for(int i=1; i<=k; i++) //问题个数
{
cin>>p[i].mount;
memset(p[i].s,0,sizeof(p[i].s));
for(int j=1; j<=p[i].mount; j++) //每个问题的单词数
{
cin>>l;
for(int t=1; t<=n; t++)
{
if(!strcmp(l,sr[t]))
{
p[i].s[j]=t;
break;
}
}
}
}
/*输出
for(int i=1;i<=k;i++)
{
for(int j=1;j<=p[i].mount;j++)
cout<<p[i].s[j]<<" ";
}
cout<<endl;*/
int min_p=99999,min_r=1,flag=0;
do
{
int nixu=nixudui();
/*
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;*/
for(int i=1; i<=k; i++)
{
int j=1,t=1;
while(j<=n&&t<=p[i].mount)
{
if(a[j]==p[i].s[t])
{
j++;
t++;
}
else
t++;
}
if(j>n)
{
if(min_p>=nixu)
{
if(min_p==nixu)
min_r=min(min_r,i);
else
{
min_p=nixu;
min_r=i;
}
flag=1;
}
//cout<<min_p<<" "<<min_r<<endl;
}
}
}
while(next_permutation(a+1,a+1+n));
if(!flag)
{
cout<<"Brand new problem!"<<endl;
return 0;
}
cout<<min_r<<endl;
cout<<"[:";
for(int i=1; i<=n*(n-1)/2-min_p+1; i++)
{
cout<<"|";
}
cout<<":]"<<endl;
return 0;
}
然后用n个子串去匹配k组字符串,求最小的逆序对。。。
在匹配k组字符串时出现问题,因为k组字符串中的单词会重复,所以不知怎么去取舍,我是用贪心的方法如果两个单词相等,则比较相邻两个单词,如果前一个单词比后面一个单词大,则删掉,事实这种方法不对,然而我想不到逆向思维,就是利用next_permutation(),求出每个下一个排列中的逆序对,然后再去匹配k组字符串,由于下一个排列中的逆序对是递增的,而且数据小,所以可以很快得出,但是注意一点(刚开始没注意,后来去查数据,唉~~我知道查数据这种方式不太对,但是我感觉自己想不出原因,所以重视忍不住去查数据,这种学习方法已经很多年了,我知道不好,但是不知怎么去改;额),当两个排列的逆序对相等时,要求出的是最小序号,所以每一个排列都要检索。。。。
代码写的很挫~~~感觉还不如大一的人~~~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m,k,a[20];
struct node
{
int s[30];
int mount;
} p[20];
char sr[20][25];
int nixudui()
{
int cnt=0;
for(int i=1; i<=n; i++)
{
for(int j=i+1; j<=n; j++)
{
if(a[i]>a[j])
cnt++;
}
}
return cnt;
}
int main()
{
cin>>n;
char l[30];
for(int i=1; i<=n; i++)
{
cin>>sr[i];
a[i]=i;
}
cin>>k;
for(int i=1; i<=k; i++) //问题个数
{
cin>>p[i].mount;
memset(p[i].s,0,sizeof(p[i].s));
for(int j=1; j<=p[i].mount; j++) //每个问题的单词数
{
cin>>l;
for(int t=1; t<=n; t++)
{
if(!strcmp(l,sr[t]))
{
p[i].s[j]=t;
break;
}
}
}
}
/*输出
for(int i=1;i<=k;i++)
{
for(int j=1;j<=p[i].mount;j++)
cout<<p[i].s[j]<<" ";
}
cout<<endl;*/
int min_p=99999,min_r=1,flag=0;
do
{
int nixu=nixudui();
/*
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;*/
for(int i=1; i<=k; i++)
{
int j=1,t=1;
while(j<=n&&t<=p[i].mount)
{
if(a[j]==p[i].s[t])
{
j++;
t++;
}
else
t++;
}
if(j>n)
{
if(min_p>=nixu)
{
if(min_p==nixu)
min_r=min(min_r,i);
else
{
min_p=nixu;
min_r=i;
}
flag=1;
}
//cout<<min_p<<" "<<min_r<<endl;
}
}
}
while(next_permutation(a+1,a+1+n));
if(!flag)
{
cout<<"Brand new problem!"<<endl;
return 0;
}
cout<<min_r<<endl;
cout<<"[:";
for(int i=1; i<=n*(n-1)/2-min_p+1; i++)
{
cout<<"|";
}
cout<<":]"<<endl;
return 0;
}
相关文章推荐
- Transformation 能将 Windows XP/Server 2003 操作系统,完美地模拟成 Windows Vista 的软件
- 用javascript和css模拟select的脚本
- PHP模拟asp.net的StringBuilder类实现方法
- C#使用ImitateLogin模拟登录百度
- javascript用层模拟可移动的小窗口
- 自编jQuery插件实现模拟alert和confirm
- JS模拟按钮点击功能的方法
- PHP模拟asp中response类实现方法
- 模拟Spring的简单实现
- javascript 模拟点击广告
- JQuery中模拟image的ajaxPrefilter与ajaxTransport处理
- php实现模拟post请求用法实例
- JavaScript实现MIPS乘法模拟的方法
- 模拟xcopy的函数
- JS模拟实现Select效果代码
- php模拟服务器实现autoindex效果的方法
- C# SendInput 模拟鼠标操作的实现方法
- PHP模拟登陆163邮箱发邮件及获取通讯录列表的方法
- js实现模拟银行卡账号输入显示效果
- JS模拟并美化的表单控件完整实例