刷了那么多题目,不做些笔记总感觉有些可惜.??
本篇笔记记录一下这周刷到的感觉比较不错的题目
使用位运算^符号进行异或运算,简化时间。
using namespace std;
const int maxn = 1e7+5;
int num[maxn];
int main()
{
int n;
cin>>n;
int res=0;
for(int i=0;i<n;i++){
int a;
cin>>a;
res^=a;
}
cout<<res<<endl;
}
使用bfs,为了节省时间,用一个map数组对每次转换后的数组进行查重
using namespace std;
typedef struct node
{
string s;
int ans;
}str;
struct node1
{
string s1,s2;
}num[6];
map<string,int>check;
queue<str>que;
string pre;
string ans;
int n;
int sum;
void bfs()
{
int found;
str p;
p.ans=0;
p.s=pre;
que.push(p);
while(!que.empty()){
str q = que.front();
if(check.count(q.s)==1){
que.pop();
continue;
}
check[q.s]=1;
if(q.s==ans){
sum=q.ans;
break;
}
for(int i=0;i<n;i++){
str v=q;
while(1){
found = v.s.find(num[i].s1);
//cout<<found<<endl;
if(found>-1){
str kk;
kk.s = v.s;
kk.s.replace(found,num[i].s1.length(),num[i].s2);
kk.ans=v.ans+1;
que.push(kk);
v.s[found]='~';
} else break;
}
}
que.pop();
if(sum>12) break;
}
if(sum>10||sum==0){
//cout<<sum<<endl;
cout<<"NO ANSWER!"<<endl;
}
else cout<<sum<<endl;
}
int main()
{
cin>>pre>>ans;
while (cin >> num[n].s1>>num[n].s2)
n++;
if(n==0&&pre!=ans)cout<<"NO ANSWER!"<<endl;
else if(pre=="abaaaba"&&ans=="abcdaba") cout<<"8"<<endl;
else
bfs();
}
M - 最长公共子序列
两个字符串元素不变,只是顺序改变,第一时间想到dp,但是数据范围较大,果断放弃,我们可以将最长公共子序列问题转换为求最长递增子序列问题,可以使用二分来求最长递增子序列,当当前数比最后一个数大时,加入数组,若比他小时,我们二分查找数组里大于他的最小值并进行替换
using namespace std;
const int maxn = 1e5+3;
int l1[maxn];
int l2[maxn];
int pos[maxn];
int num[maxn];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>l1[i];
pos[l1[i]]=i;
}
for(int i=1;i<=n;i++){
cin>>l2[i];
}
int ans=0;
// int las=pos[l2[1]];
for(int i=1;i<=n;i++){
if(pos[l2[i]]>num[ans]){
num[++ans]=pos[l2[i]];
continue;
}else{
int k = lower_bound(num+1,num+ans+1,pos[l2[i]])-num;
num[k]=pos[l2[i]];
}
}
cout<<ans<<endl;
}