簡單的模擬(洛谷)

向前走別回頭發表於2018-11-05

ACM題集:https://blog.csdn.net/weixin_39778570/article/details/83187443
P1003 鋪地毯
題目:https://www.luogu.org/problemnew/show/P1003
解法:找最後鋪到指定點的地毯,我們不妨倒著鋪地毯,第一個鋪的就是答案了

#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
const int maxn = 1e4;
int n,x[maxn+5],y[maxn+5],g[maxn+5],k[maxn+5],a,b;
int main(){
	scanf("%d",&n);
	fo(i,1,n){
		scanf("%d%d%d%d",&x[i],&y[i],&g[i],&k[i]);
	}
	scanf("%d%d",&a,&b);
	for(int i=n;i>=1;i--){
		if(a>=x[i]&&a<=x[i]+g[i] && b>=y[i]&&b<=y[i]+k[i]){
			printf("%d\n",i);
			return 0;
		}
	} 
	printf("-1\n");
	return 0;
}

P1067 多項式輸出
題目:https://www.luogu.org/problemnew/show/P1067
題意:模擬多項式輸出
解法:需要注意的點,係數的正負,負的情況想是否為-1,正的情況下是否為1,特判這兩種情況,最後注意下一次項和常數項。

#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i) 
using namespace std;
const int maxn = 105;
int a[maxn],n;
int main(){
	scanf("%d",&n);
	fo(i,0,n){
		scanf("%d",&a[i]);
	}
	bool fir = 1;
	fo(i,0,n-2){
		if(a[i]==0)continue;
		if(a[i]>0){
			if(a[i]==1&&fir)printf("x^%d",n-i),fir=0;
			else if(a[i]==1)printf("+x^%d",n-i);
			else if(fir)printf("%dx^%d",a[i],n-i),fir=0;
			else   printf("+%dx^%d",a[i],n-i);
		}else if(a[i]<0){
			if(a[i]==-1)printf("-x^%d",n-i),fir=0;
			else printf("%dx^%d",a[i],n-i),fir=0;
		}
	}
	if(n-1>=0 && a[n-1]!=0){
		if(a[n-1]>0){
			if(a[n-1]==1&&fir)printf("x"),fir=0;
			else if(a[n-1]==1)printf("+x");
			else if(fir)printf("%dx",a[n-1]),fir=0;
			else   printf("+%dx",a[n-1]);
		}else{
			if(a[n-1]==-1)printf("-x"),fir=0;
			else printf("%dx",a[n-1]),fir=0;
		}
	}
	if(a[n]!=0){
		if(a[n]>0){
			if(fir)printf("%d",a[n]),fir=0;
			else   printf("+%d",a[n]);
		}else{
			printf("%d",a[n]);
		}
	}
	return 0;
}

P1540 機器翻譯
題目:https://www.luogu.org/problemnew/show/P1540
解法:用列隊模擬一下就好,滿了就把隊頭踢掉,沒滿就把外存的單詞加進隊為(記憶體),答案+1。無聊寫了3個情況。原題輸入的“單詞”是一個很小的數。萬一數字很大呢?那就離散化一下。萬一是字串呢,那就hash一下。如下:

/*原題*/
#include<bits/stdc++.h>
#define ll long long 
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
int m,n,a[1005];
bool vis[1005];
queue<int> q;
int main(){
	cin>>m>>n;
	fo(i,1,n)cin>>a[i];
	int ans = 0;
	fo(i,1,n){
		if(!vis[a[i]]){
			vis[a[i]] = 1;
			ans++;
			q.push(a[i]);
			if(q.size()>m){
				vis[q.front()] = 0;
				q.pop();
			}
		}
	}
	cout<<ans; 
	return 0;
}
/* P1540 機器翻譯 字串hash */
#include<bits/stdc++.h>
#define ll long long 
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
map<string, int> mp;
int n,m,a[1005];
string s; 
bool vis[1005];
queue<int> q;
int main(){
	cin>>m>>n;
	int k = 1;
	fo(i,1,n){
		cin>>s;
		if(!mp[s])mp[s]=k++; // hash 
		a[i] = mp[s];
	}
	int ans = 0;
	fo(i,1,n){
		if(!vis[a[i]]){
			vis[a[i]] = 1;
			ans++;
			q.push(a[i]);
			if(q.size()>m){
				vis[q.front()] = 0;
				q.pop();
			}
		}
	}
	cout<<ans; 
}
/*P1540 機器翻譯  大數離散化 */
#include<bits/stdc++.h>
#define ll long long 
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
struct node{
	int val,  idx;
	bool operator < (const node &a)const{return val<a.val;}
}a[1005];
int m,n,ans,t[1005];
bool vis[1005];
queue<int> q;
int main(){
	scanf("%d%d",&m,&n);
	fo(i,1,n)scanf("%d",&a[i].val),a[i].idx=i;
	
	// 離散化 
	sort(a+1,a+1+n);
	int k = 0;
	t[a[1].idx] = k;
	fo(i,2,n){
		if(a[i].val!=a[i-1].val) t[a[i].idx] = ++k;
		else t[a[i].idx] = k;
	}
	// 模擬過程 
	fo(i,1,n){
		if(!vis[t[i]]){
			vis[t[i]] = 1;
			ans ++;
			q.push(t[i]);
			if(q.size()>m){
				vis[q.front()] = 0;
				q.pop();			
			}
		}
	}
	cout<<ans<<endl;
	return 0;
} 

P1056 排座椅
題目和題解:https://blog.csdn.net/weixin_39778570/article/details/83752308
P1328 生活大爆炸版石頭剪刀布
題目:https://www.luogu.org/problemnew/show/P1328
解法:用陣列模擬一下剪刀石頭布的勝負情況,注意,負的時候不扣分

/*P1328 生活大爆炸版石頭剪刀布 自己寫得跟題解差不多 */
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
int n,k1,k2,a[205],b[205];
int game[][5] = {{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}}; // 陣列一定要認真核對 
int main(){
	cin>>n>>k1>>k2;
	fo(i,1,k1)scanf("%d",&a[i]);
	fo(i,1,k2)scanf("%d",&b[i]);
	int ans1=0,ans2=0;
	fo(i,1,n){
		int t1=a[(i-1)%k1+1],t2=b[(i-1)%k2+1];
	//	cout<<t1<<" "<<t2<<endl;
		ans1 += game[t1][t2];
		ans2 += game[t2][t1];
	}
	cout<<ans1<<" "<<ans2;
	return 0;
} 

P1563 玩具謎題
題目:https://www.luogu.org/problemnew/show/P1563
解法:把這些人編號為0-n-1,方便取模。然後模擬往數還是往右數,頭朝外左邊和頭朝裡右邊往右數,其他往左數,往右加,往左減,然後取模就能模擬一個圈了,注意減法出現會出現負數,要加上取模數

#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
struct node{
	int t;
	string s;
}a[100005];
int n,m;
int main(){
	cin>>n>>m;
	fo(i,0,n-1){
		cin>>a[i].t>>a[i].s;
	}
	int now = 0;
	int t,s;
	fo(i,1,m){
		cin>>t>>s;
		if(a[now].t&&!t || !a[now].t&&t){
			now = (now+s)%n; // 0-n-1
		}else{
			now = (now-s+n)%n;
		}
	}
	cout<<a[now].s;
	return 0;
}