题目1:
输入一个N代表组数,接下来输入N组,每组2个数字空格隔开,代表线段的两端,如果存在任意一对线段存在包含关系就返回true,否则返回false.
思路:
考虑两两组合判断,时间复杂度是o(N^2),一种排序,一种不排序,但是遍历时要考虑先后包含关系。
优化算法:其实我们只需要考虑右边界
#include<bits/stdc++.h>
using namespace std;
int main(){
int N; cin>>N;
vector<vector<int>>nums(N,vector<int>(2));
for(int i=0;i<N;i++){
for(int j=0;j<2;j++)
cin>>nums[i][j];
}
//完成输入
//暴力法
bool flag=false;
sort(nums.begin(),nums.end());
int pre=-1;
for(int i=0;i<N-1;i++){
if(nums[i][1]<=pre){
flag=true;
break;
}
pre=max(pre,nums[i][1]); //记录了截至目前的右边界最大值。 如果我右侧比这个最大值要小就妥了
}
if(flag)
cout<<"true";
else
cout<<"false";
}
#include<bits/stdc++.h>
using namespace std;
int main(){
int N; cin>>N;
vector<vector<int>>nums(N,vector<int>(2));
for(int i=0;i<N;i++){
for(int j=0;j<2;j++)
cin>>nums[i][j];
}
//完成输入
//暴力法
bool flag=false;
for(int i=0;i<N-1;i++){
for(int j=i+1;j<N;j++){
if(nums[i][0]<=nums[j][0] && nums[i][1]>=nums[j][1]){
flag=true;
break;
}
if(nums[j][0]<=nums[i][0] && nums[j][1]>=nums[i][1]){
flag=true;
break;
}
}
if(flag)
break;
}
cout<<flag;
}
#include<bits/stdc++.h>
using namespace std;
int main(){
int N; cin>>N;
vector<vector<int>>nums(N,vector<int>(2));
for(int i=0;i<N;i++){
for(int j=0;j<2;j++)
cin>>nums[i][j];
}
//完成输入
//排序的话
sort(nums.begin(),nums.end()) ; //从小大到,因为是nums的元素,那就是行为基础进行排序,只会看第一个
bool flag=false;
for(int i=0;i<N-1;i++){
for(int j=i+1;j<N;j++){
if(nums[i][0]<=nums[j][0] && nums[i][1]>=nums[j][1]){
flag=true;
break;
}
}
if(flag)
break;
}
cout<<flag;
}
题目2:
多多鸡和多多鸭来打牌,每个人手上N个牌,按顺序出,多多鸡先出,依次放到桌面从左到右,如果遇到相同的牌,两个相同牌之间的牌连同该牌被出牌者收走,然后必须再出1张牌。如果打完了就其他人出,如果台面上剩余牌,奇数数值牌给多多鸡,偶数数值牌给多多鸭。输入第一行是N,第二行是多多鸡的手牌,第三行是多多鸭的手牌。
思路:
看来以后要多关注下模拟的题目,这个题目先不用想太花里胡哨的,模拟即可,因为数据范围就是牌的数值是1-13,如果数字比较小,就模拟把,出牌数量忘记了,反正也不是非常多,这个线性打出来所以速度比较快的
下面附上一种巧妙的解法和我的笨方法:
#include <bits/stdc++.h>
using namespace std;
int f(int p, vector<int> &cards)
{
int i = 0, ret = 0;
while (i != cards.size() && cards[i] != p)
++i;
if (i != cards.size())
{
ret = cards.size() - i + 1;
cards.resize(i);
}
else
cards.push_back(p);
return ret;
}
int main()
{
int N, A = 0, B = 0, i = 0, j = 0;
cin >> N;
vector<int> a(N), b(N), cards;
for (int i = 0; i < N; ++i)
cin >> a[i];
for (int i = 0; i < N; ++i)
cin >> b[i];
while (i < N || j < N)
{
while (i < N)
{
int t = f(a[i++], cards);
A += t;
if (t == 0)
break;
}
while (j < N)
{
int t = f(b[j++], cards);
B += t;
if (t == 0)
break;
}
}
for (auto i : cards)
i % 2 ? A++ : B++;
cout << A << " " << B << "\n";
}
#include<bits/stdc++.h>
using namespace std;
int main(){
int N; cin>>N;
vector<int>res1(N); vector<int>res2(N);
for(int i=0;i<N;i++)
cin>>res1[i];
for(int j=0;j<N;j++)
cin>>res2[j];
//完成输入,进入模拟阶段
stack<int>stk; vector<int>nums;
unordered_map<int,int> map;//Value和index
int i=0,j=0,count1=0,count2=0;
while( i<N || j<N ){
if(!map.count(res1[i]) && i<N) {
map[res1[i]]=nums.size(); nums.push_back(res1[i]); stk.push(res1[i]);i++;
} //如果是哈希表里面没有出现过的
else if(map.count(res1[i]) && i<N){
count1++;
int del=map[res1[i]]; nums.erase(nums.begin()+del,nums.end());
unordered_map<int,int>::iterator it;
while(stk.top()!=res1[i]){ //也就是这里进栈了 出问题了
cout<<stk.top()<<" ";
int temp=stk.top(); stk.pop(); count1++;
//删除哈希表元素
for(it=map.begin();it!=map.end();it++){
if(it->first==temp){
map.erase(it);
break;
}
}
}
for(it=map.begin();it!=map.end();it++){
if(it->first==res1[i]){
map.erase(it);
break;
}
}
stk.pop(); count1++; i++;
continue;
}//如果哈希表里面出现过了
//
if(!map.count(res2[j]) && j<N) {
map[res2[j]]=nums.size(); nums.push_back(res2[j]);stk.push(res2[j]);j++;
} //如果是哈希表里面没有出现过的
在这里改下吧,
else if(map.count(res2[j]) && j<N){
count2++;
int del=map[res2[j]]; nums.erase(nums.begin()+del,nums.end());
unordered_map<int,int>::iterator it;
while(stk.top()!=res2[j]){
int temp=stk.top(); stk.pop(); count2++;
for(it=map.begin();it!=map.end();it++){
if(it->first==temp){
map.erase(it);
break;
}
}
}
for(it=map.begin();it!=map.end();it++){
if(it->first==res2[j]){
map.erase(it);
break;
}
}
stk.pop(); count2++; j++;
///接着走,新的元素没出现就过了
if(!map.count(res2[j]) && j<N ) {
map[res2[j]]=nums.size(); nums.push_back(res2[j]); stk.push(res2[j]);j++;
}
else if(map.count(res2[j]) && j<N){ //如果出现了
while(map.count(res2[j]) && j<N){
count2++;
int del=map[res2[j]]; nums.erase(nums.begin()+del,nums.end());
unordered_map<int,int>::iterator it;
while(stk.top()!=res2[j]){ //也就是这里进栈了 出问题了
int temp=stk.top(); stk.pop(); count2++;
//删除哈希表元素
for(it=map.begin();it!=map.end();it++){
if(it->first==temp){
map.erase(it);
break;
}
}
}
for(it=map.begin();it!=map.end();it++){
if(it->first==res2[j]){
map.erase(it);
break;
}
}
stk.pop(); count2++; j++;
}
}
}
}
//输出结果
for(int i=0;i<nums.size();i++){
if(nums[i]%2)
count1++;
if(nums[i]%2==0)
count2++;
}
int size=nums.size();
cout<<count1<<" "<<count2<<" "<<size;
}
题目3:
第三题是比如集合原来有个A元素,然后我们设置输入一个B和C元素,A+B和A*C都是集合的元素,然后根据BC来不断扩充集合,现在我们有一个target值,如果target值在集合中,我们输出1,不在集合我们输出0.给N组这样的数,来输出0 1这样的列向量。
思路:
一开始我是用优先队列和哈希表来实现,但是只能过百分之15,可能要加上long吧,忘记加了,然后其实不用优先队列,我在队列里面加个条件都必须小于target才能进,这样反而会节省排序时间。下面的懒得改了。 哈希表是为了避免重复的扩张。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n; cin>>n;
vector<vector<int>>nums(n,vector<int>(4));
for(int i=0;i<n;i++){
for(int j=0;j<4;j++)
cin>>nums[i][j];
}
//完成输入 进行计算环节
vector<int>res(n,0);
//用队列的形式把
for(int i=0;i<n;i++){
priority_queue<int,vector<int>,greater<int> >q;
unordered_set<int>set;
int b=nums[i][1],c=nums[i][2],target=nums[i][3];
q.push(nums[i][0]);set.insert(nums[i][0]);
while(!q.empty() && q.top()<=target){
int size=q.size();
for(int i=0;i<size;i++){
int temp=q.top();q.pop();
int nb=temp+b,nc=temp*c;
if(!set.count(nb)){
q.push(nb);
set.insert(nb);
}
if(!set.count(nc)){
q.push(nc);
set.insert(nc);
}
} //for循环结束
if(set.count(target)){
res[i]=1;
break;
}
}/while
cout<<res[i]<<'\n';
}//循环结束
}
其实正确的思路是,注意到扩张的元素中包含了A+B,A+2B,A+NB和 AC,ACC。。。。可能会重复,但是不管怎么说,数字如果比原来的大就可能了。大致分为2类。如果存在,target-A 应该是B的倍数,如果满足就直接return1了,如果不满足,就A=AC;,然后这个新的A看看是不是B的倍数~这样。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n; cin>>n;
vector<vector<int>>nums(n,vector<int>(4));
for(int i=0;i<n;i++){
for(int j=0;j<4;j++)
cin>>nums[i][j];
}
//完成输入 进行计算环节
vector<int>res(n,0);
//用队列的形式把
for(int i=0;i<n;i++){
int A=nums[i][0],b=nums[i][1],c=nums[i][2],target=nums[i][3];
while(A<=target){
if((target-A)%b==0){ //如果A是target就出现1了
res[i]=1; break;
}
A=A*c;
}
cout<<res[i]<<'\n';
}//循环结束
}