20516林子鈞
給一張可以表示國家位置的圖
要用盡量少的顏色把國家著色
(只有上下左右是相鄰)
30*30的矩陣
0為沒有國家
其他的為國家編號(1到99之間)
以小寫英文字母來表示顏色
輸出30*30的矩陣代表地圖上國家的顏色
不存在國家時輸出'
void dfs(int pos){
visited[pos]=1;
for(auto i:graph[pos]){
if(visited[i]==0)dfs(pos);
}
}
int ma[30][30];//存圖
set<int> gra[100];//存鄰接關係
int color[100]={},iru[100]={},cnt=0;//color:存國家對應顏色 iru:存國家編號是否存在 cnt:存國家數
void dfs(int pos){
set<int> se;//存鄰國顏色
for(auto i:gra[pos]){//遍歷鄰國,紀錄顏色
if(color[i])se.insert(color[i]);
}
int i=1;auto ind=se.begin();
for(;i<=se.size();i++){
if((*ind)!=i&&color[pos]==0)color[pos]=i;//找出不在鄰國中的最小顏色
ind++;
}
if(color[pos]==0)color[pos]=i;
for(auto i:gra[pos]){
if(color[i]==0)dfs(i);//遍歷未著色鄰國
}
}
int main(){
for(int i=0;i<30;i++){
for(int j=0;j<30;j++){
char a,b;scanf("%c",&a);scanf("%c",&b);//輸入
if(b>='0'&&b<='9')ma[i][j]=(a-'0')*10+b-'0';
else ma[i][j]=a-'0';
if(ma[i][j]==0)continue;
if(iru[ma[i][j]])ma[i][j]=iru[ma[i][j]];//已編號國家直接存
else iru[ma[i][j]]=(++cnt),ma[i][j]=iru[ma[i][j]];//未編號國家拿新編號
}
}
for(int i=0;i<30;i++){
for(int j=0;j<30;j++){//建立鄰接關係
if(i!=0){
if(ma[i-1][j]!=0&&ma[i][j]!=0)gra[ma[i][j]].insert(ma[i-1][j]),gra[ma[i-1][j]].insert(ma[i][j]);
}
if(j!=0){
if(ma[i][j-1]!=0&&ma[i][j]!=0)gra[ma[i][j]].insert(ma[i][j-1]),gra[ma[i][j-1]].insert(ma[i][j]);
}
}
}
dfs(1);//著色
for(int i=0;i<30;i++){//輸出
if(color[ma[i][0]])cout<<(char)('a'+color[ma[i][0]]-1);
else cout<<'`';
for(int j=1;j<30;j++){
if(color[ma[i][j]])cout<<" "<<(char)('a'+color[ma[i][j]]-1);
else cout<<" `";
}cout<<endl;
}
return 0;
}
給你量杯數量\(n\)與量杯容量\(a_i\)
能做的操作有倒滿量杯、倒光量杯
、從一杯水倒到另一杯水
問特定容量\(t\)能否被量出
第一行有一個量杯數量 n(\(1\leq n \leq 5\))
第二行有 n個數字
分別代表每一個量杯的容量(\(1\leq a_i \leq 50\))
第三行有一個數字t(\(1\leq t \leq 50\))
代表要量出的水量
輸出一個數字
有解時輸出最少步驟數
無解時輸出-1
輸入:
3
5 8 11
2
輸出:
4
while(queue.size()){
int front=queue.front();queue.pop();
for(auto i:front){
if(visited[i]==0)queue.push(i),visited[i]=1;
}
}
把一個序列對應到一個數
實現快速判斷序列相同
\((\Sigma a_i*p^{n-i})\%M\)
p是個比p大的質數
M是個夠大的質數
int n,arr[5]={},t,ans=-1,anss,cnt=0,pos=1;//n:量杯數量 arr:量杯容量 t:要求容量 ans:答案 cnt:目前步驟數
pair<int,vector<int>> stat[10000000];
const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
struct chash {
int operator()(int x) const { return x ^ RANDOM; }
};
gp_hash_table<int,bool> ma;//存hash值
//map<int,bool> ma;
queue<pair<vector<int>,int>,list<pair<vector<int>,int>>> q;//bfs用 queue
const ll MOD=1e9+7;
const ll mul=1117;
inline bool check(vector<int> a){//檢查hash值
ll val=0;
for(int i=0;i<n;i++)val+=a[i],val=(val*mul)%MOD;
if(ma[val])return 0;
else return 1;
}
inline void add(vector<int> a){//新增hash值
ll val=0;
for(int i=0;i<n;i++)val+=a[i],val=(val*mul)%MOD;
ma[val]=1;
return ;
}
int main(){
clock_t st,no;
cin>>n;
for(int i=0;i<n;i++)cin>>arr[i];
cin>>t;//輸入
st=clock();
int g=arr[0],big=1;//g:存gcd big:紀錄有無比要求容量小的量杯
for(int i=0;i<n;i++){
if(arr[i]==t){//判掉一步解方便後續程式設計
cout<<1<<endl;
return 0;
}
if(arr[i]>t)big=0;//判掉要求容量大於每個杯子
g=__gcd(g,arr[i]);//判掉gcd不合的解
}
if(big||(t%g)){
cout<<-1<<endl;
return 0;
}
vector<int> sta,tmp;
sta.reserve(5);tmp.reserve(5);
for(int i=0;i<n;i++)sta.pb(0);//初始狀態
stat[0].F=-1;
stat[0].S=sta;
q.push(mp(sta,0));
while(q.size()){//bfs
cnt++;
no=clock();
cout<<cnt<<" "<<double(no-st)/CLOCKS_PER_SEC<<"秒"<<endl;
int siz=q.size();
while(siz--){//同一步驟數一起跑
sta=q.front().F;int now=q.front().S;q.pop();
for(int i=0;i<n;i++){
if(sta[i]!=arr[i]){//倒滿
tmp=sta;tmp[i]=arr[i];
if(check(tmp)){
stat[pos].F=now;
stat[pos].S=tmp;
q.push(mp(tmp,pos)),add(tmp);pos++;
}
}
}
for(int i=0;i<n;i++){
if(sta[i]!=0){//清空
tmp=sta;tmp[i]=0;
if(check(tmp)){
stat[pos].F=now;
stat[pos].S=tmp;
q.push(mp(tmp,pos)),add(tmp);pos++;
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i!=j)if(sta[i]!=0&&(arr[j]-sta[j])){//i倒到j
tmp=sta;
ll ttmp=min(tmp[i],arr[j]-tmp[j]);
tmp[j]+=ttmp;
tmp[i]-=ttmp;
if((tmp[i]==t||tmp[j]==t)&&ans==-1)ans=cnt,anss=pos;//檢查答案
if(check(tmp)){
stat[pos].F=now;
stat[pos].S=tmp;
q.push(mp(tmp,pos)),add(tmp);pos++;
}
}
}
}
}
if(ans!=-1)break;
}
no=clock();
cout<<ans<<endl;//" "<<double(no-st)/CLOCKS_PER_SEC<<"秒"<<endl;
stack<vector<int>> Qq;
while(stat[anss].F!=-1){
Qq.push(stat[anss].S);
anss=stat[anss].F;
}
while(Qq.size()){
for(auto i:Qq.top())cout<<i<<" ";
cout<<endl;Qq.pop();
}
return 0;
}
給你直線的兩端點
畫出直線
有四個數\(x_1,y_1,x_2,y_2\)
分別代表第一個點的x,y座標
跟第二的點的x,y座標
輸出一個字元矩陣
*代表直線經過的點
O代表直線兩端點
其餘輸出一格空白
輸入:7 1 2 2
輸出:
char cor[101][101];//儲存圖
int main(){
int x,y,dx,dy;
cin>>x>>y>>dx>>dy;
if(x>dx)swap(x,dx),swap(y,dy);//交換順序方便後續迴圈設計
for(int i=1;i<=100;i++)for(int j=1;j<=100;j++)cor[i][j]=' ';//初始化
int tmp=y;//儲存當前y座標值
for(int i=x;i<=dx;i++){//以i遍歷x座標
if(y>dy){//y由大到小
while(tmp>dy&&abs((y-dy)*(i-x)-(y-tmp)*(dx-x))>=abs((y-dy)*(i-x)-(y-tmp+1)*(dx-x))){
tmp--;cor[i][tmp]='*'; //當y-1比y距離線更近 畫點並y--
}cor[i][tmp]='*';
}else{
while(tmp<dy&&abs((dy-y)*(i-x)-(tmp-y)*(dx-x))>=abs((dy-y)*(i-x)-(tmp+1-y)*(dx-x))){
tmp++;cor[i][tmp]='*';//當y+1比y距離線更近 畫點並y++
}cor[i][tmp]='*';
}
}
cor[x][y]='O';cor[dx][dy]='O';//設定兩端點
for(int i=1;i<=100;i++){
for(int j=1;j<=100;j++){
cout<<cor[i][j];//輸出
}cout<<endl;
}
return 0;
}
給你橢圓方程式
\(a^2x^2+b^2y^2+ab=0\)
的a跟b
畫出以原點為中心的橢圓
有兩個數\(a,b\)
分別代表方程式中的\(a,b\)
輸出一個字元矩陣
*代表橢圓經過的點
其餘輸出一格空白
輸入:10 10
輸出:
char arr[200][200];//儲存輸出的圖
int main(){
int sx,sy,a,b;cin>>sx>>sy>>a>>b;
double aa=a,bb=b;//轉為double
for(int i=0;i<200;i++)for(int j=0;j<200;j++)arr[i][j]=' ';//初始化
int x=0,y=b;double d=bb*bb+aa*aa*(bb-0.5)*(bb-0.5)-aa*aa*bb*bb;//xy座標,判別式量值
arr[sx][sy+b]='*';//畫圖
arr[sx][sy-b]='*';
arr[sx][sy+b]='*';
arr[sx][sy-b]='*';
while(1){
if(d<0){//判別式小於0
d+=bb*bb*(2*(double)x+3);//更新辦別式差值
x++;//更新座標
}else{
d+=bb*bb*(2*(double)x+3)+aa*aa*(-2*(double)y+2);//更新辦別式差值
x++;y--;//更新座標
}
arr[sx+x][sy+y]='*';//畫圖
arr[sx-x][sy+y]='*';
arr[sx+x][sy-y]='*';
arr[sx-x][sy-y]='*';
if(bb*bb*((double)x+1)>=aa*aa*((double)y-0.5))break;
}
d=bb*bb*((double)x+0.5)*((double)x+0.5)+aa*aa*((double)y-1)*((double)y-1)-aa*aa*bb*bb;//重設判別式
while(1){
if(d<0){//判別式小於0
d+=bb*bb*(2*(double)x+2)+aa*aa*(-2*(double)y+1);//更新辦別式差值
x++;y--;//更新座標
}else{
d+=aa*aa*(-2*(double)y+1);//更新辦別式差值
y--;//更新座標
}
arr[sx+x][sy+y]='*';//畫圖
arr[sx-x][sy+y]='*';
arr[sx+x][sy-y]='*';
arr[sx-x][sy-y]='*';
if(y<=0)break;
}
for(int i=0;i<200;i++){
for(int j=0;j<200;j++){
cout<<arr[i][j];//輸出
}cout<<endl;
}
return 0;
}